FS Minifilter and the missing CREATEs

Hi,

I need a little help with FS Minifilter and file contexts.

PROBLEM STATEMENT:
=> How can I identify a particular file (whose IRP_MJ_CREATE have been missed) and associate a file context with it in a time complexity of O(1)…?

INTRODUCTION:
I’m writing a FS minifilter driver that would track changes in a list of files and maintain them in a bitmap.
And to save the trouble to have to string compare the file path during every IRP_MJ_WRITE (so as to check whether the file has been set for tracking), I’m setting a File Context in the IRP_MJ_CREATE itself, to all files that are found in my tracking list.
That is the only place where I have to do a string comparison of the file path.
Down the line, during any of the IRP_MJ_WRITEs all I have to do is check for the context and if it exists, it means that this file has been set for tracking.
Then I can straight away move on to updating the bitmap.

NOW HERE’S THE PROBLEM:
There might be files in the system that were open before my driver started, or in my case, before my driver was installed.
It means that I have missed the IRP_MJ_CREATE for such files, and with that I have missed my chance to set the file context which will supposedly help me identify whether changes to this file are to be tracked or not.

=> Is there a way that I can set a context to such already opened files so that I could fetch the context in the consequent IRP_MJ_WRITEs…?

PROPOSED SOLUTIONS:
The first solution that comes to mind is to string compare the file path in the IRP_MJ_WRITEs and if the file is found to be one from the tracking list, then you set the context.
But it would mean that if there are 100 open files in the system and not a single one of them falls in our tracking list, we’d DELAY the WRITE operations of all of these files.

Another thing one could do is demand a System reboot after installation of my software and have the minifilter driver load at System boot so that we won’t miss any of the IRP_MJ_CREATEs, as the driver will be loaded and ready before a file is accessed in the system.
But we don’t have the liberty to ask for a System reboot either.

There are various approaches I have devised that would reduce the expected delay in processing IRP_MJ_WRITEs, but it still leaves the non-relevant IRP_MJ_WRITEs ending up with a small hit of unnecessary extra processing.

The best thing would be to be able to set the file context (to files whose CREATEs we have missed) in a time complexity of O(1).

Any help would be greatly appreciated.
Thanks

What about setting a context on every file successfully opened. In the
allocated context mark it as one you have found in your list, or not.
Then in the write callback, if you do not find a context for a given
file then you need to allocate one and determine if it is one in your
list. If you do find a context, then it will indicate whether it is one
of interest, or not.

It reduces the times which you need to actually do additional processing
in your write routine.

Pete

On 1/2/2014 2:34 PM, xxxxx@gmail.com wrote:

Hi,

I need a little help with FS Minifilter and file contexts.

PROBLEM STATEMENT:
=> How can I identify a particular file (whose IRP_MJ_CREATE have been missed) and associate a file context with it in a time complexity of O(1)…?

INTRODUCTION:
I’m writing a FS minifilter driver that would track changes in a list of files and maintain them in a bitmap.
And to save the trouble to have to string compare the file path during every IRP_MJ_WRITE (so as to check whether the file has been set for tracking), I’m setting a File Context in the IRP_MJ_CREATE itself, to all files that are found in my tracking list.
That is the only place where I have to do a string comparison of the file path.
Down the line, during any of the IRP_MJ_WRITEs all I have to do is check for the context and if it exists, it means that this file has been set for tracking.
Then I can straight away move on to updating the bitmap.

NOW HERE’S THE PROBLEM:
There might be files in the system that were open before my driver started, or in my case, before my driver was installed.
It means that I have missed the IRP_MJ_CREATE for such files, and with that I have missed my chance to set the file context which will supposedly help me identify whether changes to this file are to be tracked or not.

=> Is there a way that I can set a context to such already opened files so that I could fetch the context in the consequent IRP_MJ_WRITEs…?

PROPOSED SOLUTIONS:
The first solution that comes to mind is to string compare the file path in the IRP_MJ_WRITEs and if the file is found to be one from the tracking list, then you set the context.
But it would mean that if there are 100 open files in the system and not a single one of them falls in our tracking list, we’d DELAY the WRITE operations of all of these files.

Another thing one could do is demand a System reboot after installation of my software and have the minifilter driver load at System boot so that we won’t miss any of the IRP_MJ_CREATEs, as the driver will be loaded and ready before a file is accessed in the system.
But we don’t have the liberty to ask for a System reboot either.

There are various approaches I have devised that would reduce the expected delay in processing IRP_MJ_WRITEs, but it still leaves the non-relevant IRP_MJ_WRITEs ending up with a small hit of unnecessary extra processing.

The best thing would be to be able to set the file context (to files whose CREATEs we have missed) in a time complexity of O(1).

Any help would be greatly appreciated.
Thanks


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

This whole approach presupposes that there is path information available for any file operation aside from the CREATE. While you can use FltGetFileNameInformation in any callback, it can be ridiculously expensive. It would probably be a better approach to enumerate open handles and add them to your tracking table instead as you are starting up.

I don’t have a suggested method for doing that.

Phil

Not speaking for LogRhythm
Phil Barila | Senior Software Engineer
720.881.5364 (w)
The Security Intelligence Company?
A LEADER 2013 SIEM Magic Quadrant
Perfect 5-Star Rating in SC Magazine for 5 Consecutive Years

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Peter Scott
Sent: Thursday, January 02, 2014 2:50 PM
To: Windows File Systems Devs Interest List
Subject: Re: [ntfsd] FS Minifilter and the missing CREATEs

What about setting a context on every file successfully opened. In the allocated context mark it as one you have found in your list, or not.
Then in the write callback, if you do not find a context for a given file then you need to allocate one and determine if it is one in your list. If you do find a context, then it will indicate whether it is one of interest, or not.

It reduces the times which you need to actually do additional processing in your write routine.

Pete

On 1/2/2014 2:34 PM, xxxxx@gmail.com wrote:

Hi,

I need a little help with FS Minifilter and file contexts.

PROBLEM STATEMENT:
=> How can I identify a particular file (whose IRP_MJ_CREATE have been missed) and associate a file context with it in a time complexity of O(1)…?

INTRODUCTION:
I’m writing a FS minifilter driver that would track changes in a list of files and maintain them in a bitmap.
And to save the trouble to have to string compare the file path during every IRP_MJ_WRITE (so as to check whether the file has been set for tracking), I’m setting a File Context in the IRP_MJ_CREATE itself, to all files that are found in my tracking list.
That is the only place where I have to do a string comparison of the file path.
Down the line, during any of the IRP_MJ_WRITEs all I have to do is check for the context and if it exists, it means that this file has been set for tracking.
Then I can straight away move on to updating the bitmap.

NOW HERE’S THE PROBLEM:
There might be files in the system that were open before my driver started, or in my case, before my driver was installed.
It means that I have missed the IRP_MJ_CREATE for such files, and with that I have missed my chance to set the file context which will supposedly help me identify whether changes to this file are to be tracked or not.

=> Is there a way that I can set a context to such already opened files so that I could fetch the context in the consequent IRP_MJ_WRITEs…?

PROPOSED SOLUTIONS:
The first solution that comes to mind is to string compare the file path in the IRP_MJ_WRITEs and if the file is found to be one from the tracking list, then you set the context.
But it would mean that if there are 100 open files in the system and not a single one of them falls in our tracking list, we’d DELAY the WRITE operations of all of these files.

Another thing one could do is demand a System reboot after installation of my software and have the minifilter driver load at System boot so that we won’t miss any of the IRP_MJ_CREATEs, as the driver will be loaded and ready before a file is accessed in the system.
But we don’t have the liberty to ask for a System reboot either.

There are various approaches I have devised that would reduce the expected delay in processing IRP_MJ_WRITEs, but it still leaves the non-relevant IRP_MJ_WRITEs ending up with a small hit of unnecessary extra processing.

The best thing would be to be able to set the file context (to files whose CREATEs we have missed) in a time complexity of O(1).

Any help would be greatly appreciated.
Thanks


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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


Kernel Drivers
Windows File System and Device Driver Consulting www.KernelDrivers.com
866.263.9295


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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

Thanks Peter and Phil for your quick responses.

Then in the write callback, if you do not find a context for a given
file then you need to allocate one and determine if it is one in your
list.
=> Determining whether the file is in my list in the WRITEs would be expensive.
Because there could be 100s of open files in the system that I’m getting WRITEs for, and for all of these files I’ll end up fetching complete file path and matching it against 100s of files that I might have in my list.
The irrelevant files (i.e. those that are not on the list) will unnecessarily take a performance hit on each and every one of their WRITE operations. The users would be like “Oh my system’s gone slow ever since I installed this minifilter driver”.

It would probably be a better approach to enumerate open handles and add them to
your tracking table instead as you are starting up.
=> I was thinking of something on similar lines Phil, that maybe there is a way to enumerate the open file objects and perhaps associate a file context with it.
Because in the end, it’s an object in the kernel memory. If the file object pointer would remain the same for both, the process accessing the file and the one supplied to the minifilter driver in its callbacks, and if I could get my hands on all such open file object pointers I think maybe I can compare the file pointers to check if it’s a file on my list.

By the way, I forgot to mention that I’ve replied back to your comments inline in my previous message, i.e. Message #4.
I’d hate for it to get overlooked due to a silly mistake. :slight_smile:

Agreed, on the first time the file was accessed in the write path it
would take a performance hit but after that single hit you would have
the information and there would no further performance hits. So over
time, a pretty short interval if there is lots of activity on these open
files, your list would grow to contain all open files.

The enumeration of all open file instances would eliminate this
processing, though via the Flt API this is not currently possible, or
maybe there is a new API that I am not aware of … Phil?

Pete

On 1/2/2014 4:20 PM, xxxxx@gmail.com wrote:

Thanks Peter and Phil for your quick responses.

> Then in the write callback, if you do not find a context for a given
file then you need to allocate one and determine if it is one in your
list.
=> Determining whether the file is in my list in the WRITEs would be expensive.
Because there could be 100s of open files in the system that I’m getting WRITEs for, and for all of these files I’ll end up fetching complete file path and matching it against 100s of files that I might have in my list.
The irrelevant files (i.e. those that are not on the list) will unnecessarily take a performance hit on each and every one of their WRITE operations. The users would be like “Oh my system’s gone slow ever since I installed this minifilter driver”.

> It would probably be a better approach to enumerate open handles and add them to
your tracking table instead as you are starting up.
=> I was thinking of something on similar lines Phil, that maybe there is a way to enumerate the open file objects and perhaps associate a file context with it.
Because in the end, it’s an object in the kernel memory. If the file object pointer would remain the same for both, the process accessing the file and the one supplied to the minifilter driver in its callbacks, and if I could get my hands on all such open file object pointers I think maybe I can compare the file pointers to check if it’s a file on my list.


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

> Hi,

I need a little help with FS Minifilter and file contexts.

PROBLEM STATEMENT:
=> How can I identify a particular file (whose IRP_MJ_CREATE have been
missed) and associate a file context with it in a time complexity of
O(1)…?

INTRODUCTION:
I’m writing a FS minifilter driver that would track changes in a list of
files and maintain them in a bitmap.
And to save the trouble to have to string compare the file path during
every IRP_MJ_WRITE (so as to check whether the file has been set for
tracking), I’m setting a File Context in the IRP_MJ_CREATE itself, to all
files that are found in my tracking list.
That is the only place where I have to do a string comparison of the file
path.
Down the line, during any of the IRP_MJ_WRITEs all I have to do is check
for the context and if it exists, it means that this file has been set for
tracking.
Then I can straight away move on to updating the bitmap.

What, exactly, does the bitmap do? Or are you dealing with image files of
some kind?

As far as I know, the FsContext and FsContext2 are private to the file
system and cannot be changed or modified in any way. What, exactly, are
you setting?

NOW HERE’S THE PROBLEM:
There might be files in the system that were open before my driver
started, or in my case, before my driver was installed.
It means that I have missed the IRP_MJ_CREATE for such files, and with
that I have missed my chance to set the file context which will supposedly
help me identify whether changes to this file are to be tracked or not.

=> Is there a way that I can set a context to such already opened files so
that I could fetch the context in the consequent IRP_MJ_WRITEs…?

PROPOSED SOLUTIONS:
The first solution that comes to mind is to string compare the file path
in the IRP_MJ_WRITEs and if the file is found to be one from the tracking
list, then you set the context.
But it would mean that if there are 100 open files in the system and not a
single one of them falls in our tracking list, we’d DELAY the WRITE
operations of all of these files.

It sounds to me like you only need to delay the FIRST write you see for an
“unmarked” file. That is, your decision is three-state: care, don’t care,
don’t know. Once you determine that the state is “don’t know”, you only
need to delay that one write long enough to decide whether it should be
marked “care” or “don’t care”, and therefore on subsequent write
operations, no string compares are required.

Another thing one could do is demand a System reboot after installation of
my software and have the minifilter driver load at System boot so that we
won’t miss any of the IRP_MJ_CREATEs, as the driver will be loaded and
ready before a file is accessed in the system.
But we don’t have the liberty to ask for a System reboot either.

This would be silly. You have to work on the premise that you cannot
demand a reboot and that there may already be open files. But see my
above description of the three-state issue.

There are various approaches I have devised that would reduce the expected
delay in processing IRP_MJ_WRITEs, but it still leaves the non-relevant
IRP_MJ_WRITEs ending up with a small hit of unnecessary extra processing.

No, it is not “unnecessary”; from the viewpoint of your filter driver,
that processing is essential. But you only need to do it once per file,
on the first write operation you intercept for a “don’t know” file. Once
you have determined whether or not you care, the lengthy computation never
again needs to be done.

The best thing would be to be able to set the file context (to files whose
CREATEs we have missed) in a time complexity of O(1).

You can already do that for files you create. But it isn’t O(1) even in
that case; it is a function of the number of files in the “catch table”
(or the number of extensions, depending on what you are trying to catch).
Therefore, the first write operation will be delayed by O(k), whereas for
files being newly created, the create will be delayed by O(k), where k is
the cost of determining if the file is of interest. There is no reason to
ever perform this lookup more than once on an unmarked file; once it is
performed, you mark the file, and everything beyond that point works in
O(1) time (where 1 represents the cost of asking “care or don’t care?”)

I note that you have not said what the purpose of this detection is; if it
is one of those “we want to make sure nobody is doing X to files of type
Y”, note that there is absolutely, positively, no conceivable way you can
tell anything about the type of data in a file. Extensions are a hint of
what the content might be, but I can save a JPEG file as .BMP, .EXE, or
.TXT. Note that if I try to read that file with Paint, or run it, or read
it in NotePad, I will get errors or gibberish, but file content is not
compelled to match the extension. So it is not clear what purpose this
minifilter serves.
joe

Any help would be greatly appreciated.
Thanks


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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 meant to add that k in my O(k) is not a constant, but a formula, e.g.,
log n, n^2, etc.

However, big-O notation is a shorthand for a much more complex equation

O(e) = t[setup] + C * e + t[teardown]

Usually, t[setup] and t[teardown] are extremely close to, or exactly,
zero, and can be ignored. But that big-C is a potential killer. C is the
“constant of proportionality” that converts the value determined by the
expression e to actual time. It may be that e is a simple “n log n”, as
for a sort, but C is the cost of doing the comparison, and can be very
large. I once had a case where the cost of strcmp dominated everything.
So I sorted the global symbol table once, associated each string with an
integer, e.g. s[i] ~ v[i], where s is a string and v is an integer value,
or, for all i, j if v[i] < v[j], then s[i] < s[j] (and there are no
duplicates, so although the same relationship held for ==, it didn’t
matter). Reduced sorting large string sets from minutes to seconds (yes,
there was a reason to sort them multiple times, using multiple keys, but
only one key was a string).

So what you have observed is that if you have to repeat a complex test on
every write, C becomes extremely large, even if e is log n (e.g., binary
search) or even if e is a constant (e.g., under a perfect hash, e == 1,
and under less-than-perfect hash, you can usually get e == 1.2 without
killer effort), so C does not have to dominate. And it puts the delay,
uniformly, into every file, precisely once. So always be cautious of that
C, it can kill you. O(1) is not very good if that one test involves a disk
read, for example, to perform the test. An O(n^2) done entirely in memory
needs a pretty large n before it loses to the O(1) requiring a disk
access.
joe

> Hi,
>
> I need a little help with FS Minifilter and file contexts.
>
> PROBLEM STATEMENT:
> => How can I identify a particular file (whose IRP_MJ_CREATE have been
> missed) and associate a file context with it in a time complexity of
> O(1)…?
>
> INTRODUCTION:
> I’m writing a FS minifilter driver that would track changes in a list of
> files and maintain them in a bitmap.
> And to save the trouble to have to string compare the file path during
> every IRP_MJ_WRITE (so as to check whether the file has been set for
> tracking), I’m setting a File Context in the IRP_MJ_CREATE itself, to
> all
> files that are found in my tracking list.
> That is the only place where I have to do a string comparison of the
> file
> path.
> Down the line, during any of the IRP_MJ_WRITEs all I have to do is check
> for the context and if it exists, it means that this file has been set
> for
> tracking.
> Then I can straight away move on to updating the bitmap.

What, exactly, does the bitmap do? Or are you dealing with image files of
some kind?

As far as I know, the FsContext and FsContext2 are private to the file
system and cannot be changed or modified in any way. What, exactly, are
you setting?

>
> NOW HERE’S THE PROBLEM:
> There might be files in the system that were open before my driver
> started, or in my case, before my driver was installed.
> It means that I have missed the IRP_MJ_CREATE for such files, and with
> that I have missed my chance to set the file context which will
> supposedly
> help me identify whether changes to this file are to be tracked or not.
>
> => Is there a way that I can set a context to such already opened files
> so
> that I could fetch the context in the consequent IRP_MJ_WRITEs…?
>
> PROPOSED SOLUTIONS:
> The first solution that comes to mind is to string compare the file path
> in the IRP_MJ_WRITEs and if the file is found to be one from the
> tracking
> list, then you set the context.
> But it would mean that if there are 100 open files in the system and not
> a
> single one of them falls in our tracking list, we’d DELAY the WRITE
> operations of all of these files.

It sounds to me like you only need to delay the FIRST write you see for an
“unmarked” file. That is, your decision is three-state: care, don’t care,
don’t know. Once you determine that the state is “don’t know”, you only
need to delay that one write long enough to decide whether it should be
marked “care” or “don’t care”, and therefore on subsequent write
operations, no string compares are required.

>
> Another thing one could do is demand a System reboot after installation
> of
> my software and have the minifilter driver load at System boot so that
> we
> won’t miss any of the IRP_MJ_CREATEs, as the driver will be loaded and
> ready before a file is accessed in the system.
> But we don’t have the liberty to ask for a System reboot either.

This would be silly. You have to work on the premise that you cannot
demand a reboot and that there may already be open files. But see my
above description of the three-state issue.

>
> There are various approaches I have devised that would reduce the
> expected
> delay in processing IRP_MJ_WRITEs, but it still leaves the non-relevant
> IRP_MJ_WRITEs ending up with a small hit of unnecessary extra
> processing.

No, it is not “unnecessary”; from the viewpoint of your filter driver,
that processing is essential. But you only need to do it once per file,
on the first write operation you intercept for a “don’t know” file. Once
you have determined whether or not you care, the lengthy computation never
again needs to be done.

>
> The best thing would be to be able to set the file context (to files
> whose
> CREATEs we have missed) in a time complexity of O(1).

You can already do that for files you create. But it isn’t O(1) even in
that case; it is a function of the number of files in the “catch table”
(or the number of extensions, depending on what you are trying to catch).
Therefore, the first write operation will be delayed by O(k), whereas for
files being newly created, the create will be delayed by O(k), where k is
the cost of determining if the file is of interest. There is no reason to
ever perform this lookup more than once on an unmarked file; once it is
performed, you mark the file, and everything beyond that point works in
O(1) time (where 1 represents the cost of asking “care or don’t care?”)

I note that you have not said what the purpose of this detection is; if it
is one of those “we want to make sure nobody is doing X to files of type
Y”, note that there is absolutely, positively, no conceivable way you can
tell anything about the type of data in a file. Extensions are a hint of
what the content might be, but I can save a JPEG file as .BMP, .EXE, or
.TXT. Note that if I try to read that file with Paint, or run it, or read
it in NotePad, I will get errors or gibberish, but file content is not
compelled to match the extension. So it is not clear what purpose this
minifilter serves.
joe
>
> Any help would be greatly appreciated.
> Thanks
>
> —
> NTFSD is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
> For our schedule of debugging and file system 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
>


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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

Hey everybody,

After having done a bunch of tryouts we discovered a way to avoid the expensive search operations through our tracking list in the WRITE path.
We’d like to know more about this behaviour and whether any of you see any possible drawbacks of using this approach.

Here’s a list of steps:

  1. Once we have received a new file to be added for tracking, we open the file (from either the user/kernel mode) which generates a CREATE for that file and then immediately close it.
    (Note: This file may have been opened before our driver was installed, meaning that some other process might hold an open handle to the file already by the time it has been added for tracking. And we’re specially targeting this case using this solution.)
  2. Now that we have received a CREATE, we’ll first check whether a file context is set or not. If there is no context, it means that either this is the first CREATE for this file or that this file was opened by some process earlier and our driver wasn’t loaded at that time. In either case, we’ll check whether the file is present in our tracking list and we set the context here.
  3. Here’s the exciting part: The context that we’ve set here automatically starts getting reflected in the callbacks for all the other already open instances of the same file. Meaning that if we call FltGetFileContext() in the WRITE/READ/etc. path of a file whose CREATE we had missed, the call succeeds and it returns the context that we had set in Step 2 above.

This context remains for that particular file even when all open handles to the file are eventually closed, i.e. after closing all open handles to that file if we newly open the same file again and the driver calls FltGetFileContext() on that file, the call succeeds and returns the context that was set earlier by us.

Please share your views about this approach.

Thanks

Although that looks like it should work, it seems kind of expensive. I haven’t looked into the method Process Explorer uses to enumerate currently open files, so it may be worse that what you’ve done, but I’m pretty sure it doesn’t require IO against the open handle in order to detect them.

Sysinternals used to publish the source to the Handle tool, among others, until someone reused it without appropriate attribution and/or compensation. Then they only licensed it if you paid for it. Then MSFT bought Sysinternals, and stopped licensing it altogether.

Mark is pretty forthcoming, and while he’s not going to give away IP, he’d probably steer you to the basic methodology that he uses in Process Explorer if you ask him. The Sysinternals forum is a good place for information.

Phil B

Not speaking for LogRhythm
Phil Barila | Senior Software Engineer
720.881.5364 (w)
The Security Intelligence Company?
A LEADER 2013 SIEM Magic Quadrant
Perfect 5-Star Rating in SC Magazine for 5 Consecutive Years

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, January 20, 2014 12:36 PM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] FS Minifilter and the missing CREATEs

Hey everybody,

After having done a bunch of tryouts we discovered a way to avoid the expensive search operations through our tracking list in the WRITE path.
We’d like to know more about this behaviour and whether any of you see any possible drawbacks of using this approach.

Here’s a list of steps:

  1. Once we have received a new file to be added for tracking, we open the file (from either the user/kernel mode) which generates a CREATE for that file and then immediately close it.
    (Note: This file may have been opened before our driver was installed, meaning that some other process might hold an open handle to the file already by the time it has been added for tracking. And we’re specially targeting this case using this solution.) 2. Now that we have received a CREATE, we’ll first check whether a file context is set or not. If there is no context, it means that either this is the first CREATE for this file or that this file was opened by some process earlier and our driver wasn’t loaded at that time. In either case, we’ll check whether the file is present in our tracking list and we set the context here.
  2. Here’s the exciting part: The context that we’ve set here automatically starts getting reflected in the callbacks for all the other already open instances of the same file. Meaning that if we call FltGetFileContext() in the WRITE/READ/etc. path of a file whose CREATE we had missed, the call succeeds and it returns the context that we had set in Step 2 above.

This context remains for that particular file even when all open handles to the file are eventually closed, i.e. after closing all open handles to that file if we newly open the same file again and the driver calls FltGetFileContext() on that file, the call succeeds and returns the context that was set earlier by us.

Please share your views about this approach.

Thanks


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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 believe Mark must have used NtQuerySystemInformation() to enumerate open handles of running processes.
But thanks for the tip Phil, I guess I’ll start a discussion on the SysInternals forum.

Cheers

For me, this is absolutely the way the FltMgr contexts were designed for, and a good way.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntfsd…
> Hey everybody,
>
> After having done a bunch of tryouts we discovered a way to avoid the expensive search operations through our tracking list in the WRITE path.
> We’d like to know more about this behaviour and whether any of you see any possible drawbacks of using this approach.
>
> Here’s a list of steps:
> 1. Once we have received a new file to be added for tracking, we open the file (from either the user/kernel mode) which generates a CREATE for that file and then immediately close it.
> (Note: This file may have been opened before our driver was installed, meaning that some other process might hold an open handle to the file already by the time it has been added for tracking. And we’re specially targeting this case using this solution.)
> 2. Now that we have received a CREATE, we’ll first check whether a file context is set or not. If there is no context, it means that either this is the first CREATE for this file or that this file was opened by some process earlier and our driver wasn’t loaded at that time. In either case, we’ll check whether the file is present in our tracking list and we set the context here.
> 3. Here’s the exciting part: The context that we’ve set here automatically starts getting reflected in the callbacks for all the other already open instances of the same file. Meaning that if we call FltGetFileContext() in the WRITE/READ/etc. path of a file whose CREATE we had missed, the call succeeds and it returns the context that we had set in Step 2 above.
>
> This context remains for that particular file even when all open handles to the file are eventually closed, i.e. after closing all open handles to that file if we newly open the same file again and the driver calls FltGetFileContext() on that file, the call succeeds and returns the context that was set earlier by us.
>
> Please share your views about this approach.
>
> Thanks
>

Thanks a lot Maxim for your confirmation.
What is the lifecycle of the FileContext…?
We’ve observed that the FileContext remains up until the driver is unloaded.

Is there any documentation about this behaviour of the FltMgr…?
It’d be great to learn more about the way it handles different kinds of contexts.

If you want to know how process explorer works internally, look at process
hacker
http://processhacker.sourceforge.net/

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Phil Barila
Sent: 20 January 2014 19:47
To: Windows File Systems Devs Interest List
Subject: RE: RE:[ntfsd] FS Minifilter and the missing CREATEs

Although that looks like it should work, it seems kind of expensive. I
haven’t looked into the method Process Explorer uses to enumerate currently
open files, so it may be worse that what you’ve done, but I’m pretty sure it
doesn’t require IO against the open handle in order to detect them.

Sysinternals used to publish the source to the Handle tool, among others,
until someone reused it without appropriate attribution and/or compensation.
Then they only licensed it if you paid for it. Then MSFT bought
Sysinternals, and stopped licensing it altogether.

Mark is pretty forthcoming, and while he’s not going to give away IP, he’d
probably steer you to the basic methodology that he uses in Process Explorer
if you ask him. The Sysinternals forum is a good place for information.

Phil B

Not speaking for LogRhythm
Phil Barila | Senior Software Engineer
720.881.5364 (w)
The Security Intelligence Company?
A LEADER 2013 SIEM Magic Quadrant
Perfect 5-Star Rating in SC Magazine for 5 Consecutive Years

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Monday, January 20, 2014 12:36 PM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] FS Minifilter and the missing CREATEs

Hey everybody,

After having done a bunch of tryouts we discovered a way to avoid the
expensive search operations through our tracking list in the WRITE path.
We’d like to know more about this behaviour and whether any of you see any
possible drawbacks of using this approach.

Here’s a list of steps:

  1. Once we have received a new file to be added for tracking, we open the
    file (from either the user/kernel mode) which generates a CREATE for that
    file and then immediately close it.
    (Note: This file may have been opened before our driver was installed,
    meaning that some other process might hold an open handle to the file
    already by the time it has been added for tracking. And we’re specially
    targeting this case using this solution.) 2. Now that we have received a
    CREATE, we’ll first check whether a file context is set or not. If there is
    no context, it means that either this is the first CREATE for this file or
    that this file was opened by some process earlier and our driver wasn’t
    loaded at that time. In either case, we’ll check whether the file is present
    in our tracking list and we set the context here.
  2. Here’s the exciting part: The context that we’ve set here automatically
    starts getting reflected in the callbacks for all the other already open
    instances of the same file. Meaning that if we call FltGetFileContext() in
    the WRITE/READ/etc. path of a file whose CREATE we had missed, the call
    succeeds and it returns the context that we had set in Step 2 above.

This context remains for that particular file even when all open handles to
the file are eventually closed, i.e. after closing all open handles to that
file if we newly open the same file again and the driver calls
FltGetFileContext() on that file, the call succeeds and returns the context
that was set earlier by us.

Please share your views about this approach.

Thanks


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system 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