Okay first a little context. I have started working on a project in my uni, one of the goals of which are to develop a module that will log when a process tries to:
-create, delete or modify a file (filesystem activity basically)
-create, detete or modify a registry id/value
We will actually be specifying a process for this module to monitor, and whenever this process tries to perform any of the activities listed above it will get logged.
Right now, i am looking into the basics of Driver development, and Filter Drivers as suggested by my DS. Here is my question,
What would be the best method to achieve this, would it be by writing a filter driver of some sort? if yes than exactly what filter driver, a filesystem filter driver or a minifilter driver or something else? Or don't know maybe some other technique?
I just need a little direction, so that i can do targeted research and implementation, as i don't have much time for this project!
File system minifilter drivers is the way to do this.
But the tricky part would be how do specify process to monitor. If you are thinking of PID then its quite straight forward, but if you are thinking of using process/executable name like notepad.exe then that becomes little complicated.
Just to give you hint, you can get PID for the operation in mini filter but not process name. So you will have to maintain a map of PID to process name in your minifilter driver. You way want to use PsSetCreateProcessNotifyRoutineEx and PsSetLoadImageNotifyRoutine.
Related
I am new to windows filter drivers. From the sample code of (MSDN) what I have seen is that, File system filter driver, has Filter Manager associated with it, and process filter driver doesn't have Filter Manager associated with it. So why is that difference?
So need some suggestions and help.
It seems that you might want to read Windows Internals by Alex Ionescu, this will clear things up for you, starting from the bottom and will help you understand the whole thing.
Basically, in the past, filesystem filter drivers were built in a way that it would sit in a the right position in the exact filesystem DEVICE STACK, for example, NTFS. That way it would get the chance to filter IRPs.
Nowadays, the thing you mentioned, the filter manager (FLTMGR) has its own (legacy) driver at the top and on the bottom of the device stack, and it lets you register a callback function that everytime an IRP gets caughted, you'll get a chance to handle it.
Process (creation/deletion) filtering is a bit different, it is not handled using IRPs, basically in the call flow of NtCreateUserProcess on the kernel side there is a function responsible for calling whatever function registered for this kind of callback.
I hope that it clears things for you.
When an application process launches an XPC helper process, it doesn't actually do the fork()/exec() itself in the classic UNIX style. Instead, it sends a message to launchd, which does the dirty work for it. Thus, if you query the parent process on the XPC process, it comes back as the launchd process.
However, if you open Activity Monitor in the hierarchical process view, the XPC helper processes are all shown below the original application that requested them, for example:
In the software I'm working on, knowing this relationship between processes would be extremely useful. So far we've been using the regular BSD parent process information, but as everything moves towards XPC, this isn't much use anymore.
So:
Where is the "original" parent process information stored for XPC processes?
How does Activity Monitor access it?
There is a kext involved, so I'd be happy to pull this information straight out in the kernel instead of userspace, but I can't seem to even figure out where it's stored.
Update: Discussion on Apple's darwin-kernel mailing list: http://lists.apple.com/archives/darwin-kernel/2015/Mar/msg00001.html
I imagine that launchd knows what you are looking for.
The Service Management framework has a method that might give you what you are looking for easily.
CFDictionaryRef SMJobCopyDictionary(CFStringRef domain, CFStringRef jobLabel); function.
I am trying to get file open/write/create operation, I have tried fslogger which can only get file creation/delete....and other operations, can not get open/close operation,
then I wrote a driver to do it, I can get open/close operation but can not get create operation, what's more, it's too messy!
for example, if I open a file and modify it, and then close it, the driver gets a lot of open/write operations..I have no way to tell which one is really caused by user open/close operation..
any hints about this?
thanks.
Your best bet is going to be the KAuth system. You install your kauth handler (as a kernel extension) and get various callback codes when someone tries to create, open or close a file. This involves getting your callback in the critical path of opening files, so whatever you do has to be quick!
To quote:
KAUTH_SCOPE_FILEOP defines the following actions.
KAUTH_FILEOP_OPEN
KAUTH_FILEOP_CLOSE
KAUTH_FILEOP_CLOSE_MODIFIED
KAUTH_FILEOP_RENAME
KAUTH_FILEOP_EXCHANGE
KAUTH_FILEOP_LINK
KAUTH_FILEOP_EXEC
https://developer.apple.com/library/mac/technotes/tn2127/_index.html
If you're writing a kext you then have the question of how to get that info back into userland. FWIW I used Kqueue but you may have success with another method (let me know in the comments if you do!).
More info on Kauth here and KQueue here. It's not brilliantly documented, but there's enough info between those two to work out what you need to do.
Is there any way to hook all disk writes going thru the system, and receive the file names of whatever's being modified, using the Win32 API? Or is this something that would require writing a driver?
You can't do this in user mode, it needs to be kernel mode and so that means a driver. You need a File System Filter Driver.
If you don't care about intercepting the actual data, and only want to know which files are being modified/created/deleted then you can use the ReadDirectoryChangesW API to get that info from userland. Note however that it's one of the hardest functions to use effectively and efficiently, and you should be familiar with IOCP to use it correctly.
This is intended to be a lightweight generic solution, although the problem is currently with a IIS CGI application that needs to log the timeline of events (second resolution) for troubleshooting a situation where a later request ends up in the MySQL database BEFORE the earlier request!
So it boils down to a logging debug statements in a single text file.
I could write a service that manages a queue as suggested in this thread:
Issue writing to single file in Web service in .NET
but deploying the service on each machine is a pain
or I could use a global mutex, but this would require each instance to open and close the file for each write
or I could use a database which would handle this for me, but it doesnt make sense to use a database like MySQL to try to trouble shoot a timeline issue with itself. SQLite is another possability, but this thread
http://www.perlmonks.org/?node_id=672403
Suggests that it is not a good choice either.
I am really looking for a simple approach, something as blunt as writing to individual files for each process and consolidating them accasionally with a scheduled app. I do not want to over engineer this, nor spend a week implementing it. It is only needed occassionally.
Suggestions?
Try the simplest solution first - each write to the log opens and closes the file. If you experience problems with this, which you probably won't , look for another solution.
You can use file locking. Lock the file for writing, write the message, unlock.
My suggestion is to preserve performance then think in asynchronous logging. Why not send your data log info using UDP to service listening port and he write to log file.
I would also suggest some kind of a central logger that can be called by each process in an asynchronous way. If the communication is UDP or RPC or whatever would be an implementation detail.
Even thought it's an old post, has anyone got an idea why not using the following concept:
Creating/opening a file with share mode of FILE_SHARE_WRITE.
Having a named global mutex, and opening it.
Whenever a file write is desired, lock the mutex first, then write to the file.
Any input?