Minifilter Cryptography. Problems with memory mapped files.

Hi all.
I’m writing a Minifilter which does cryptography on file basis.
The fact is that I have some problems working with memory mapped files.
I started using the swapbuffers example, and then I added cryptography
on the buffer swapped.
The code works well with buffered IO (wordpad).
But it has problems when using with notepad (which uses memory mapped
files).
I intercept paging operations (with PAGING_IO flag set), and i threat
them correctly.But when i open the file with notepad i see it undeciphered.
Why this happens? Should i also intercept IRP_MJ_MDL_READ/WRITE?

And please explain me a thing, if I decipher PAGING IO READ , this means
that the cache will be plain, correct? (Because an attempt to read the
cache when the part of the file is not there generates a PAGE_FAULT).The
page is then retrieved and put in the cache deciphered (I should be able
to intercept cache manager paging operations right? ) .
If i intercept a FASTIO or a cached IRP, this means i shall not decipher
the read buffer again, do I?

Thank you for your help, any reply will be appreciated.
Regards
Marco Montesissa.

> And please explain me a thing, if I decipher PAGING IO READ , this means

that the cache will be plain, correct?

Yes. This is OK.

If i intercept a FASTIO or a cached IRP, this means i shall not decipher
the read buffer again, do I?

Yes. You only do your crypto in noncached IO paths, paging and non-paging
(read/write to the file opened without caching).

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

First of all, thank you for your reply,
I followed these instructions, but my filter doesn’t behave correctly, i
mean, when a file is opened in memory mapped is still seen as scrambled.
Furthermore, i noticed that when i use the Image previewer of windows
and i rotate the image (just to do some few tests), the write bypasses
the filter and writes down the image plain to the disc (my prewrite is
never called, neither in fastio, neither with paging for cache
flushing.). (Maybe there’s another path for reads and writes?)

Thank you

> And please explain me a thing, if I decipher PAGING IO READ , this means
> that the cache will be plain, correct?
>

Yes. This is OK.

> If i intercept a FASTIO or a cached IRP, this means i shall not decipher
> the read buffer again, do I?
>

Yes. You only do your crypto in noncached IO paths, paging and non-paging
(read/write to the file opened without caching).

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com


Questions? First check the IFS FAQ at https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@tin.it
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hi,
When I started to develop my encryption minifilter driver I had the same
problem. In post-operation for CREATE request I call my function
EfIsFileEncrypted to determine encrypted files. In function
EfIsFileEncrypted I read file header like this using FltReadFile:
status = FltReadFile(FltObjects->Instance,
FltObjects->FileObject,
&byteOffset,
readLen,
buffer,
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET,
&bytesRead,
NULL,
NULL);

But in this case data is reading from disk and this encrypted data is
writing also to cache. And if user program read file then data is reading
from cache, so program see encrypted data.
To solve this problem I specify FLTFL_IO_OPERATION_NON_CACHED flag:
status = FltReadFile(FltObjects->Instance,
FltObjects->FileObject,
&byteOffset,
readLen,
buffer,
FLTFL_IO_OPERATION_NON_CACHED |
FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET,
&bytesRead,
NULL,
NULL);

After this my filter driver work with mapped files correct.

Best regards,
Victor Fisyuk
EMail/MSN: xxxxx@rambler.ru
Web: http://rockdbg.siteburg.com

“[DF]Nester” wrote in message news:xxxxx@ntfsd…
> Hi all.
> I’m writing a Minifilter which does cryptography on file basis.
> The fact is that I have some problems working with memory mapped files.
> I started using the swapbuffers example, and then I added cryptography
> on the buffer swapped.
> The code works well with buffered IO (wordpad).
> But it has problems when using with notepad (which uses memory mapped
> files).
> I intercept paging operations (with PAGING_IO flag set), and i threat
> them correctly.But when i open the file with notepad i see it
> undeciphered.
> Why this happens? Should i also intercept IRP_MJ_MDL_READ/WRITE?
>
> And please explain me a thing, if I decipher PAGING IO READ , this means
> that the cache will be plain, correct? (Because an attempt to read the
> cache when the part of the file is not there generates a PAGE_FAULT).The
> page is then retrieved and put in the cache deciphered (I should be able
> to intercept cache manager paging operations right? ) .
> If i intercept a FASTIO or a cached IRP, this means i shall not decipher
> the read buffer again, do I?
>
> Thank you for your help, any reply will be appreciated.
> Regards
> Marco Montesissa.
>
>

Victor Fisyuk ha scritto:

But in this case data is reading from disk and this encrypted data is
writing also to cache. And if user program read file then data is reading
from cache, so program see encrypted data.
To solve this problem I specify FLTFL_IO_OPERATION_NON_CACHED flag:

Thank you victor for your advice, i used FLTFL_IO_OPERATION_PAGING_IO
becuase with NON_CACHED it didn’t work.
Now i think it’s working, I still have some problems to cheat on EOF, i
mean the file size.
Sometimes my file gets truncated and i don’t know why , i intercept
SET_INFORMATION and cheat EOF and ALLOCATIONSIZE.
Do you think there’s another path where applications or the system sets
EOF of files?
Thank you

Marco Montesissa.

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of [DF]Nester
Sent: Monday, May 08, 2006 10:30
To: Windows File Systems Devs Interest List
Subject: Re: [ntfsd] Minifilter Cryptography. Problems with
memory mapped files.

Victor Fisyuk ha scritto:
> But in this case data is reading from disk and this
encrypted data is
> writing also to cache. And if user program read file then data is
> reading from cache, so program see encrypted data.
> To solve this problem I specify FLTFL_IO_OPERATION_NON_CACHED flag:
>
Thank you victor for your advice, i used
FLTFL_IO_OPERATION_PAGING_IO becuase with NON_CACHED it didn’t work.
Now i think it’s working, I still have some problems to cheat
on EOF, i mean the file size.
Sometimes my file gets truncated and i don’t know why , i
intercept SET_INFORMATION and cheat EOF and ALLOCATIONSIZE.
Do you think there’s another path where applications or the
system sets EOF of files?
Thank you

Perhaps I didn’t understand your problem at all, but to me it seems you’re
not intercepting IO for FileObjects created by the kernel. When you have an
IRP_MJ_OMG you need to check that the PFILE_OBJECT should be intercepted by
looking at its FCB. So it means you need to have a collection of some sort
that will store all file objects to intercept.

Have you tested your filter with streams (ooooh naughty me :p)?

Edouard

Edouard A. ha scritto:

Perhaps I didn’t understand your problem at all, but to me it seems you’re
not intercepting IO for FileObjects created by the kernel. When you have an
IRP_MJ_OMG you need to check that the PFILE_OBJECT should be intercepted by
looking at its FCB. So it means you need to have a collection of some sort
that will store all file objects to intercept.

Have you tested your filter with streams (ooooh naughty me :p)?

I actually use StreamContext, in the postcreate i read the first 512
bytes of the file and check if they match the header.
If they do then i attach a StreamContext to the FILE_OBJECT. Because the
streamcontext is attached to every file_object i should intercept it,
right? Even if it’s a kernel IO. Please let me know if I’m correct.

I jump FILE OBJECT which are stream_file object because i don’t know how
to handle them. This is a piece of code. Thanks

try {

//
// If they are trying to write ZERO bytes, or the file has been
closed by a user process then don’t do anything and
// we don’t need a post-operation callback.
//

if (writeLen == 0 || FltObjects->FileObject->Flags &
FO_STREAM_FILE) {

leave;
}

//
// Try to retrieve this file context, if there’s no context
then we don’t need to hook this operation
//

status = CtxFindOrCreateStreamContext(Data,
FALSE,
&streamContext,
&streamContextCreated);

if(!NT_SUCCESS(status)||!streamContext->isCiphered)
leave;

> Thank you victor for your advice, i used FLTFL_IO_OPERATION_PAGING_IO

becuase with NON_CACHED it didn’t work.

NON_CACHED is correct. Otherwise, any app which will open the file as noncached
and do usual Read/WriteFile to it (most database engines are such) - will see
the encrypted data.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

> I actually use StreamContext, in the postcreate i read the

first 512 bytes of the file and check if they match the header.
If they do then i attach a StreamContext to the FILE_OBJECT.
Because the streamcontext is attached to every file_object i
should intercept it, right? Even if it’s a kernel IO. Please
let me know if I’m correct.

What I understand is that you read the first 512 bytes of a file, and check
if they match a header/pattern of yours, and if this header/pattern is ok,
then you decide to process the file? It forces you to build an IRP_MJ_READ
request, no? Or you use the ZwXXX functions? What if you are at IRQL >
PASSIVE_LEVEL? Or Did I simply 100% misunderstood? :stuck_out_tongue:

I jump FILE OBJECT which are stream_file object because i
don’t know how to handle them. This is a piece of code. Thanks

Well I think the real question is what behaviour do you want to achieve? It
is highly possible you will not have to care about the streams, in which
case you are all set. :wink: It is über elite to support all the features of the
file system you are filtering, but the real question is : “do I have to?”.

(sorry for the late answer)

Edouard