Hi there,
This is my first post on this newsgroup, so please be kind with me ;).
I’m currently trying to make a little encryption filter driver.
I only want to crypt or decrypt data when they are read or written
directly from the disk to make the in memory data always in clear format
for applications and other drivers.
My problem is that I’m not sure that I’m correctly making distinction
between I/O directed to the cache and those directed to the actual
backing file on the volume. I listed the cases I thought of (maybe I
have forgotten some or be wrong on my assumptions):
For read operations:
- Irp->Flags contains IRP_NOCACHE and IRP_PAGING_IO bit NOT set thus
this should be a user mode non cached operation. In this case I need to
decrypt the buffer.
- Irp->Flags contains IRP_NOCACHE, IRP_PAGING_IO AND
IRP_SYNCHRONOUS_PAGING_IO bits set. This is supposed to be a synchronous
operation from the Memory Manager. Since this is not a FastIo I supposed
I need to decrypt the buffer there too.
- Irp->Flags contains IRP_NOCACHE AND IRP_PAGING_IO bits set. This is
supposed to be an asynchronous operation from the Memory Manager. Since
this is not a FastIo I supposed I need to decrypt the buffer there too.
- Irp->Flags doesn’t contain IRP_NOCACHE. I simply pass the request
down. Cleared data should already be avaible to the Cache Manager.
The problem for the read operation is that for application like notepad
which seems to use memory mapping of the file, I don’t see any
IRP_MJ_READ from the Memory Manager. I only receive the
AcquireForSectionSynchronization notification, but it isn’t followed by
any IRP_MJ_READ.
For write operations:
- Irp->Flags contains IRP_NOCACHE and IRP_PAGING_IO bit NOT set thus
this should be a user mode non cached operation. In this case I need to
crypt the buffer.
- Irp->Flags contains IRP_NOCACHE, IRP_PAGING_IO AND
IRP_SYNCHRONOUS_PAGING_IO bits set. I’m a bit confused here, since I
don’t know if it is a flush operation or if the data will be written in
the cache
- Irp->Flags contains IRP_NOCACHE AND IRP_PAGING_IO bits set. same as
above but in an asynchronous way.
- Irp->Flags doesn’t contain IRP_NOCACHE. I simply pass the request
down. Cleared data should already be avaible to the Cache Manager.
I don’t know if I have been relatively clear. If someone can explain the
behavior of the Memory Manager when memory mapped file are used that
would help :).
Oh, I forgot to mention. For each request that I am handling, I’m
creating a new IRP before completing the original.
P.S: I’m not using the FilterManager.
–
Mickael.
If IRP_NOCACHE is set that means the request will not go to cache manager
but to underlying FS(F)D.
So just checking for the presence/absence of IRP_NOCACHE is enough. No need
to check PAGING flags.
Even if the files are memory mapped (in your case notepad), you must see
IRP_MJ_READ. It may be possible
that the file you are trying to read is already in the system cache.
Reboot the machine. Start your filter. Read the file. Then observe.
“Barratis” wrote in message news:xxxxx@ntfsd…
> Hi there,
>
> This is my first post on this newsgroup, so please be kind with me ;).
>
> I’m currently trying to make a little encryption filter driver.
>
> I only want to crypt or decrypt data when they are read or written
> directly from the disk to make the in memory data always in clear format
> for applications and other drivers.
>
> My problem is that I’m not sure that I’m correctly making distinction
> between I/O directed to the cache and those directed to the actual
> backing file on the volume. I listed the cases I thought of (maybe I
> have forgotten some or be wrong on my assumptions):
>
> For read operations:
> - Irp->Flags contains IRP_NOCACHE and IRP_PAGING_IO bit NOT set thus
> this should be a user mode non cached operation. In this case I need to
> decrypt the buffer.
> - Irp->Flags contains IRP_NOCACHE, IRP_PAGING_IO AND
> IRP_SYNCHRONOUS_PAGING_IO bits set. This is supposed to be a synchronous
> operation from the Memory Manager. Since this is not a FastIo I supposed
> I need to decrypt the buffer there too.
> - Irp->Flags contains IRP_NOCACHE AND IRP_PAGING_IO bits set. This is
> supposed to be an asynchronous operation from the Memory Manager. Since
> this is not a FastIo I supposed I need to decrypt the buffer there too.
> - Irp->Flags doesn’t contain IRP_NOCACHE. I simply pass the request
> down. Cleared data should already be avaible to the Cache Manager.
>
> The problem for the read operation is that for application like notepad
> which seems to use memory mapping of the file, I don’t see any
> IRP_MJ_READ from the Memory Manager. I only receive the
> AcquireForSectionSynchronization notification, but it isn’t followed by
> any IRP_MJ_READ.
>
> For write operations:
> - Irp->Flags contains IRP_NOCACHE and IRP_PAGING_IO bit NOT set thus
> this should be a user mode non cached operation. In this case I need to
> crypt the buffer.
> - Irp->Flags contains IRP_NOCACHE, IRP_PAGING_IO AND
> IRP_SYNCHRONOUS_PAGING_IO bits set. I’m a bit confused here, since I
> don’t know if it is a flush operation or if the data will be written in
> the cache
> - Irp->Flags contains IRP_NOCACHE AND IRP_PAGING_IO bits set. same as
> above but in an asynchronous way.
> - Irp->Flags doesn’t contain IRP_NOCACHE. I simply pass the request
> down. Cleared data should already be avaible to the Cache Manager.
>
> I don’t know if I have been relatively clear. If someone can explain the
> behavior of the Memory Manager when memory mapped file are used that
> would help :).
>
> Oh, I forgot to mention. For each request that I am handling, I’m
> creating a new IRP before completing the original.
>
> P.S: I’m not using the FilterManager.
>
> –
> Mickael.
>
Hi,
Thanks for the answer. I effectively receive an IRP_MJ_READ with
IRP_PAGING_IO and IRP_NOCACHE flags set a little after the
AcquireSectionForSynchronization.
However I’ve got a different problem now. When I’m building a new
synchronous IRP and send it to the driver below me (in my case is
directly Ntfs). I’ve got back a STATUS_FILE_CLOSED. I’ve found other
mention of this behavior on the list, but with no solution.
Moreover, It seems like only the data fater the 4096 are requested. Is
it possible that the Ntfs’ MFT is in cause ?
I’m using directly the FileObject of the original IRP in my new one,
perhaps this is a mistake. I’ll try to find out why, but if you have any
ideas they are more than welcome :).
–
Mickael
Mani wrote:
If IRP_NOCACHE is set that means the request will not go to cache manager
but to underlying FS(F)D.
So just checking for the presence/absence of IRP_NOCACHE is enough. No need
to check PAGING flags.
Even if the files are memory mapped (in your case notepad), you must see
IRP_MJ_READ. It may be possible
that the file you are trying to read is already in the system cache.
Reboot the machine. Start your filter. Read the file. Then observe.
“Barratis” wrote in message news:xxxxx@ntfsd…
>> Hi there,
>>
>> This is my first post on this newsgroup, so please be kind with me ;).
>>
>> I’m currently trying to make a little encryption filter driver.
>>
>> I only want to crypt or decrypt data when they are read or written
>> directly from the disk to make the in memory data always in clear format
>> for applications and other drivers.
>>
>> My problem is that I’m not sure that I’m correctly making distinction
>> between I/O directed to the cache and those directed to the actual
>> backing file on the volume. I listed the cases I thought of (maybe I
>> have forgotten some or be wrong on my assumptions):
>>
>> For read operations:
>> - Irp->Flags contains IRP_NOCACHE and IRP_PAGING_IO bit NOT set thus
>> this should be a user mode non cached operation. In this case I need to
>> decrypt the buffer.
>> - Irp->Flags contains IRP_NOCACHE, IRP_PAGING_IO AND
>> IRP_SYNCHRONOUS_PAGING_IO bits set. This is supposed to be a synchronous
>> operation from the Memory Manager. Since this is not a FastIo I supposed
>> I need to decrypt the buffer there too.
>> - Irp->Flags contains IRP_NOCACHE AND IRP_PAGING_IO bits set. This is
>> supposed to be an asynchronous operation from the Memory Manager. Since
>> this is not a FastIo I supposed I need to decrypt the buffer there too.
>> - Irp->Flags doesn’t contain IRP_NOCACHE. I simply pass the request
>> down. Cleared data should already be avaible to the Cache Manager.
>>
>> The problem for the read operation is that for application like notepad
>> which seems to use memory mapping of the file, I don’t see any
>> IRP_MJ_READ from the Memory Manager. I only receive the
>> AcquireForSectionSynchronization notification, but it isn’t followed by
>> any IRP_MJ_READ.
>>
>> For write operations:
>> - Irp->Flags contains IRP_NOCACHE and IRP_PAGING_IO bit NOT set thus
>> this should be a user mode non cached operation. In this case I need to
>> crypt the buffer.
>> - Irp->Flags contains IRP_NOCACHE, IRP_PAGING_IO AND
>> IRP_SYNCHRONOUS_PAGING_IO bits set. I’m a bit confused here, since I
>> don’t know if it is a flush operation or if the data will be written in
>> the cache
>> - Irp->Flags contains IRP_NOCACHE AND IRP_PAGING_IO bits set. same as
>> above but in an asynchronous way.
>> - Irp->Flags doesn’t contain IRP_NOCACHE. I simply pass the request
>> down. Cleared data should already be avaible to the Cache Manager.
>>
>> I don’t know if I have been relatively clear. If someone can explain the
>> behavior of the Memory Manager when memory mapped file are used that
>> would help :).
>>
>> Oh, I forgot to mention. For each request that I am handling, I’m
>> creating a new IRP before completing the original.
>>
>> P.S: I’m not using the FilterManager.
>>
>> –
>> Mickael.
>>
>
>
>
I found the answer.
I wasn’t setting the flags in the right place (use the IrpStack instead
of the Irp). After having read a bit of the FastFat code, it seems that
FileObjects which have been closed are still valid for PAGING_IO operation.
So now, I manage to read data from the filesystem by sending my own IRP
down on a IRP_PAGING_IO | IRP_NOCACHE. I then decrypt the returned
buffer successfully, copy it on the buffer provided by the VMM (using
the address returned by MmGetSystemBufferForMdlSafe). But, unfortunately
it seems like the data put in the cache are the crypted one. How is this
possible ?
I’m just thinking that I’m not catching the write operation at the
moment, but I don’t think that could be related. From my understanding,
by trying to copy data from its cache to the user buffer the
CacheManager generate a Page Fault (the first time at least). Then the
VMM should make place for physical page to backup this cache and send
the irp down to the fs to fill it (IRP that I am intercepting). Once
this done, the instruction of the CacheManager is re-executed. If that’s
correct, it should have seen the decrypted data I put in the pages
reseverd by the VMM.
Any idea ?
Barratis wrote:
Hi,
Thanks for the answer. I effectively receive an IRP_MJ_READ with
IRP_PAGING_IO and IRP_NOCACHE flags set a little after the
AcquireSectionForSynchronization.
However I’ve got a different problem now. When I’m building a new
synchronous IRP and send it to the driver below me (in my case is
directly Ntfs). I’ve got back a STATUS_FILE_CLOSED. I’ve found other
mention of this behavior on the list, but with no solution.
Moreover, It seems like only the data fater the 4096 are requested. Is
it possible that the Ntfs’ MFT is in cause ?
I’m using directly the FileObject of the original IRP in my new one,
perhaps this is a mistake. I’ll try to find out why, but if you have any
ideas they are more than welcome :).
> For read operations:
- Irp->Flags contains IRP_NOCACHE and IRP_PAGING_IO bit NOT set thus
this should be a user mode non cached operation. In this case I need to
decrypt the buffer.
- Irp->Flags contains IRP_NOCACHE, IRP_PAGING_IO AND
IRP_SYNCHRONOUS_PAGING_IO bits set. This is supposed to be a
You need to decrypt in all noncached reads and to encrypt in all noncached
writes.
–
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
Checking the IRP_NOCACHE flag should be sufficient. While writing make sure
you are NOT encrypting the buffer given by VMM. You have to take the copy of
that buffer, do the encryption and send the new encrypted buffer down. Make
sure the original buffer is updated properly in the completion routine.
P.S: I’m not using the FilterManager.
It is good you are not using FilterManager.
Sisimon
Bangalore
Hi,
For Read Operation checking IRP_NOCACHE is sufficient as IRP_PAGING_IO flags always comes with IRP_NOCACHE, so encrypt the data in IRP_MJ_READ with IRP_NOCACHE flags
For Write operation again check for IRP_NOCACHE, i.e. decrypt the data in IRP_MJ_WRITE with IRP_NOCACHE.
This is sufficient for ecryption decryption filter even for memory mapped files. Try it, I am sure it will work for all files formats even the programs that are using memory mapped files.
P.S. - There is no need for AcquireForSectionSynchronization and I you try it will end up in deadlock. So Dont try that.
Thanks & Regards
Aishwary Bhashkar
Sr. Software Engineer
R Systems International Ltd.