monitor the file modification

As a newbie, I try to write a filter to monitor the modification on the
files, procedures planned are given as below, your comments and instructions
are urgently welcome.

  1. Intercept the IRP_MJ_WRITE
    — is it ok if I only monitor IRP_MJ_WRITE?

  2. Compare the SID of User and the file owner, if possible, given the alert
    information
    — I am a little confused about the owner SID and user SID, according to
    OSR IFS FAQ 35, it should retrieve the file user SID, but how can I get the
    file owner SID? so that I can compare them and give some alert information
    or log it. In short, it is kind of user access control.

  3. fetch the timestamp, log the user SID got in step 2 and timestamp
    information
    —I will use ZwQueryInformationFile() / IRP_MJ_QUERY_INFORMATION to
    fetch timestamp then log it.

  4. save the orginal file in a different name, save the modified file in
    original name.
    —confused again, when the user save the file after his modification,
    only one IRP_MJ_WRITE sending by IO manager or multiple times?
    —every modification has a different name, but the orginal file will not
    be touched.

The purpose of this filter is that when somebody modify the file, the user
information, timestamp would be logged, meanwhile, we can recover the file
back to the modification happend at a specific time.

  1. Intercept the IRP_MJ_WRITE
    — is it ok if I only monitor IRP_MJ_WRITE?

Not really. You can’t do anything by only looking at the write IRP.
You won’t know what file is being written etc. You will also need to
deal with IRP_MJ_CREATE and IRP_MJ_CLEAN/IRP_MJ_CLOSE to track the file.

  1. Compare the SID of User and the file owner, if possible, given the
    alert
    information
    — I am a little confused about the owner SID and user SID,
    according to
    OSR IFS FAQ 35, it should retrieve the file user SID, but how can I get
    the
    file owner SID? so that I can compare them and give some alert
    information
    or log it. In short, it is kind of user access control.

So, you need the file owner SID and you want the SID of the calling
thread? That is doable, but you will be opening and reading the file in
question to obtain the security object associated with the file. This
is something you can do in IRP_MJ_CREATE - in most cases. Look at file
system developer kit samples for the rules or when it is ok to pre-open
a file and query it.

  1. fetch the timestamp, log the user SID got in step 2 and timestamp
    information
    —I will use ZwQueryInformationFile() / IRP_MJ_QUERY_INFORMATION to
    fetch timestamp then log it.

Timestamps of the file? Sure, you can do that. If you are using Zw
calls, again, you have to pre-open the file or something like that. You
could also roll or query information IRP.

  1. save the orginal file in a different name, save the modified file in
    original name.
    —confused again, when the user save the file after his
    modification,
    only one IRP_MJ_WRITE sending by IO manager or multiple times?
    —every modification has a different name, but the orginal file will
    not
    be touched.

Much more complicated. This will then be an active filter modifying i/o
to the file system. This type of operation will be rather specific to
the application you are trying to support. Some apps already play
rename games with files (such as the office suite).

The purpose of this filter is that when somebody modify the file, the
user
information, timestamp would be logged, meanwhile, we can recover the
file
back to the modification happend at a specific time.

I would recommend that you develop something similar to a snapshoting
engine for doing this. You can save reverse deltas of the file being
modified to restore back. I do NOT recommend that you change the i/o to
the target file. A file level snapshotter is more like a replicator
really, except you are replicating reserve delta’s of the file. You may
also choose to just make a copy of the whole file on first modification.
You would have to hold of the write IRPs while you did your work in
either case.

WARNING: there are a number of issues involved with this, such as i/o
synchronization and file access permissions (i.e. file sharing
modes,etc.) You can play games with the i/o subsystem to circumvent
some of these problems - but it is tricky).

WARNING2: you will have to deal with fast path i/o.

This is NOT a simple filter to write.

Tom, thank you very much for your guidance.

As to question 1, right after I post my message, I realize that I need to
intercept IRP_MJ_CREATE, IRP_MJ_CLEAN/IRP_MJ_CLOSE besides the IRP_MJ_WRITE.

As to question 2 and 3, I will try as you said. But I am not sure both of
owner SID and SID of the calling thread could be found in
“Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext”.

My further question is: cause there is no security context in IRP_MJ_WRITE
parameters, I need to get SID in IRP_MJ_CREATE, however, both of Read and
Write operation will trigger the IRP_MJ_CREATE, so how do I know the SID I
got from the IRP_MJ_CREATE is right the guy who made the modification:
IRP_MJ_CREATE? E.g., two guys access to the same file, one read, one write.

As to question 4, it is a headache for me. I don’t know how to implement
what you said about “replicating reserve delta’s of the file”, if possible,
can you make it more specific?

Still, I am not so clear: how many IRP_MJ_WRITE issued for one file when it
is modified and saved? Can I intercept the file content in one of the
Irp->UserBuffer, Irp->MdlAddress, and Irp->AssociatedIrp.SystemBuffer
based on the actual situation?

Sorry for my stupid question.

Thanks again.

“Tom Hansen” xxxxx@ntfsd…

1. Intercept the IRP_MJ_WRITE
— is it ok if I only monitor IRP_MJ_WRITE?

Not really. You can’t do anything by only looking at the write IRP.
You won’t know what file is being written etc. You will also need to
deal with IRP_MJ_CREATE and IRP_MJ_CLEAN/IRP_MJ_CLOSE to track the file.

2. Compare the SID of User and the file owner, if possible, given the
alert
information
— I am a little confused about the owner SID and user SID,
according to
OSR IFS FAQ 35, it should retrieve the file user SID, but how can I get
the
file owner SID? so that I can compare them and give some alert
information
or log it. In short, it is kind of user access control.

So, you need the file owner SID and you want the SID of the calling
thread? That is doable, but you will be opening and reading the file in
question to obtain the security object associated with the file. This
is something you can do in IRP_MJ_CREATE - in most cases. Look at file
system developer kit samples for the rules or when it is ok to pre-open
a file and query it.

3. fetch the timestamp, log the user SID got in step 2 and timestamp
information
—I will use ZwQueryInformationFile() / IRP_MJ_QUERY_INFORMATION to
fetch timestamp then log it.

Timestamps of the file? Sure, you can do that. If you are using Zw
calls, again, you have to pre-open the file or something like that. You
could also roll or query information IRP.

4. save the orginal file in a different name, save the modified file in
original name.
—confused again, when the user save the file after his
modification,
only one IRP_MJ_WRITE sending by IO manager or multiple times?
—every modification has a different name, but the orginal file will
not
be touched.

Much more complicated. This will then be an active filter modifying i/o
to the file system. This type of operation will be rather specific to
the application you are trying to support. Some apps already play
rename games with files (such as the office suite).

The purpose of this filter is that when somebody modify the file, the
user
information, timestamp would be logged, meanwhile, we can recover the
file
back to the modification happend at a specific time.

I would recommend that you develop something similar to a snapshoting
engine for doing this. You can save reverse deltas of the file being
modified to restore back. I do NOT recommend that you change the i/o to
the target file. A file level snapshotter is more like a replicator
really, except you are replicating reserve delta’s of the file. You may
also choose to just make a copy of the whole file on first modification.
You would have to hold of the write IRPs while you did your work in
either case.

WARNING: there are a number of issues involved with this, such as i/o
synchronization and file access permissions (i.e. file sharing
modes,etc.) You can play games with the i/o subsystem to circumvent
some of these problems - but it is tricky).

WARNING2: you will have to deal with fast path i/o.

This is NOT a simple filter to write.

As to question 2 and 3, I will try as you said. But I am not sure both
of
owner SID and SID of the calling thread could be found in
“Parameters.Create.SecurityContext->AccessState->SubjectSecurityContext”
.

The calling thread will have a security context associated with it. The
IFS kit prototypes the necessary SE functions I think. There are a
number of functions that have the Se??? prefix that are used to get
security context etc. I think the OSR folks may even have a FAQ that
describes how to get the security context and maybe even extracting the
subject SID. Tony was discussing this topic last week on this forum and
I vaguely remember that he referenced some FAQ. Poke around
osronline.com and learn.

My further question is: cause there is no security context in
IRP_MJ_WRITE
parameters, I need to get SID in IRP_MJ_CREATE, however, both of Read
and
Write operation will trigger the IRP_MJ_CREATE, so how do I know the SID
I
got from the IRP_MJ_CREATE is right the guy who made the modification:
IRP_MJ_CREATE? E.g., two guys access to the same file, one read, one
write.

As above. The calling thread will have the security context. Also,
each process that opens the file gets a different file object - so you
can remember state about each open file and manage context about the
file that way. I personally use a hash table to map file object address
to my own reference handle. In XP and 2003 you can use stream context
in your filter.

As to question 4, it is a headache for me. I don’t know how to
implement
what you said about “replicating reserve delta’s of the file”, if
possible,
can you make it more specific?

It is really outside the scope of this forum for me to design a reverse
(not reserve) delta replicator. The basic concept is to save away the
old data for a file before it is modified - and thereby you can restore
the old data back later. I think you have a lot of research and
learning to do on this and basic filter concepts. I strongly suggest
that you don’t go into this without adequate reference and training.
OSR provides courses you might want to consider.

Still, I am not so clear: how many IRP_MJ_WRITE issued for one file when
it
is modified and saved? Can I intercept the file content in one of the
Irp->UserBuffer, Irp->MdlAddress, and Irp->AssociatedIrp.SystemBuffer
based on the actual situation?

Depends on how you are getting called and for what application. You
can’t depend on counting IRPs or assuming things about the buffer being
supplied. For big files you could get hundreds or thousands or
IRP_MJ_WRITE calls to save a file. Again, you really need to consider
some file system development training. This should not be entered into
lightly since implementing a reliable driver requires a good
understanding of the NT OS. It is possible to throw together a small
filter that functions - but you will be fixing bugs “'til the cows come
home”.

/TomH