Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTFSD

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


How to tell if a file has had a write operation in the pre-cleanup callback routine

user3211user3211 Member Posts: 2

Hi, i'm new to minifilter development. My minifilter intercepts both IRP_MJ_WRITE and IRP_MJ_CLEANUP and I need to filter for files that had been written to, in my pre-cleanup callback routine.

In my post-write callback, i call FltAllocateContext and FltSetStreamHandleContext to allocate and set a stream handle context which contains a ULONG variable to store the length of transfer in a write operation using Data->Iopb->Parameters.Write.Length.

Subsequently, in the pre-cleanup callback, i call FltGetStreamHandleContext to get a context if there was one allocated earlier. If the call is successful, i check that the ULONG variable is > 0 and if so, i deduce that the file had been written to.

May i ask if i am approaching this right? Thank you.

Comments

  • Dejan_MaksimovicDejan_Maksimovic Member - All Emails Posts: 544
    via Email
    Hi,

    You won't know in pre-cleanup if there was a right, with certainty.
    Sure, most access will show up, but some won't.
    By post-close you can know that though. That might happens an hour later
    though!

    What you want requires heuristics that is specific to your scenario.

    Regards, Dejan.
  • user3211user3211 Member Posts: 2

    Hi, may i ask why some write operations won't show up in pre-cleanup and only show up in post-close using the context approach?

    Currently, my scenario is to send files for scanning when the last user-mode applications using the files have closed their last handles to the file objects (hence pre-cleanup), but i am only interested in sending files that had write operations performed on them by user-mode applications. Thus, i am using the context approach to help me identify files that had been written to and to send for scanning when apps finished using them .


    Would this approach be enough for my scenario? Thanks.

  • Dejan_MaksimovicDejan_Maksimovic Member - All Emails Posts: 544
    via Email
    Memory mapped access will not show this way often enough. Writes are seen
    after Cleanup only.

    Dejan.
  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,590
    edited May 16

    @user3211 said:
    Hi, i'm new to minifilter development. My minifilter intercepts both IRP_MJ_WRITE and IRP_MJ_CLEANUP and I need to filter for files that had been written to, in my pre-cleanup callback routine.

    In my post-write callback, i call FltAllocateContext and FltSetStreamHandleContext to allocate and set a stream handle context which contains a ULONG variable to store the length of transfer in a write operation using Data->Iopb->Parameters.Write.Length.

    You can't do these things in PostWrite because you might be at DISPATCH_LEVEL. Better to do it in PreWrite where you know you're at IRQL <= APC_LEVEL...Sure, the write could fail, but that doesn't change the fact that the user intended to write (and failure is rare).

    Dejan is correct that this doesn't cover the case of memory mapped write. In that case the application closes their file HANDLE (* 1) and writes to the file mapping. This updates the file data copy in RAM (* 2), then the Memory Manager eventually/maybe gets around to flushing the data out as paging IRP_MJ_WRITE requests from the System process. So, your heuristic of catching the modifications at PreCleanup doesn't work. Things get worse if you have more than one application memory mapping for write as you have no idea who is actually modifying the data, just that it was modified by someone at some point.

    Two things you can do to mitigate this;

    1. You see the memory mapping happen (IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION) and that MUST happen before the HANDLE is closed. This is your hint that your heuristic doesn't apply.
    2. While memory map for READ is common, memory map for WRITE is unusual. I cover it a lot in the minifilter seminar and then once everyone is sufficiently terrified I usually advise students to a) make sure they understand the case and b) have code to detect and (importantly) log it. But don't make yourself insane if checking for non-paging writes in PreWrite along with a check in PreCleanup is usually enough for the common use cases (drag/drop, document save, etc.)

    If you're still not quite sure I highly recommend playing with FileTest and ProcMon. FileTest lets you perform whatever series of file operations you want and then see the results in ProcMon:

    http://www.zezula.net/en/fstools/filetest.html
    https://learn.microsoft.com/en-us/sysinternals/downloads/procmon

    -scott

    *1 - The user application can and usually does close the file HANDLE, but it's not a requirement in the API
    *2 - DAX (aka Persistent Memory) screws this up even further...In that case there are no IRP_MJ_WRITE requests AT ALL when dealing with memory mapped for write. It's really cool stuff, still niche and expensive at the moment though prices have come way down
    https://learn.microsoft.com/en-us/windows-server/storage/storage-spaces/persistent-memory-direct-access
    https://buy.hpe.com/us/en/options/enterprise-memory/persistent-memory/persistent-memory/intel-optane-512gb-persistent-memory-100-series-for-hpe/p/835810-b21

    -scott
    OSR

  • Dejan_MaksimovicDejan_Maksimovic Member - All Emails Posts: 544
    via Email
    Just to add: BypassIo can also bypass write filters completely, but this
    you can detect and veto.
  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,590

    @Dejan_Maksimovic said:
    Just to add: BypassIo can also bypass write filters completely, but this
    you can detect and veto.

    Also read only for now (whether or not they actually enable this in the write path is TBD...place your bets!)

    https://learn.microsoft.com/en-us/windows-hardware/drivers/ifs/bypassio

    -scott
    OSR

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Internals & Software Drivers 19-23 June 2023 Live, Online
Writing WDF Drivers 10-14 July 2023 Live, Online
Kernel Debugging 16-20 October 2023 Live, Online
Developing Minifilters 13-17 November 2023 Live, Online