How to intercept Win32 API calls with C#? - c#

I would like to either host a virtual drive and intercept the I/O, or intercept I/O calls to certain folders on a hard drive, and do arbitrary things to that call like write the file to a 2nd location. For example, if Notepad.exe writes a file to C:\Data\test.txt - I would like to have access to that file name, and the data of the file. Likewise, I would like to run arbitrary code when any user attempts to read C:\Data\test.txt or attempts to get a directory listing for C:\Data.
Ideally I want to have a handler for when a file is: created, updated, deleted, or opened - and when someone does a directory listing (from command-line or from the Shell).
I can do the write part with FileSystemWatcher - but I can't intercept disk "reads". So, I next looked into MS Detours and EasyHook. That won't really work because I'd need to monitor every single process on the computer and hook to OpenFile on ALL of them. I don't want to use a Shell Extension because this behavior needs to exist from the command-line too. So, that leaves either writing a File System MiniFilter driver - or writing my own installable file system in C++.
I can have some portion of this in C++ - although the driver stuff is a bit over my head, but ultimately most of the rest of code should be in C#, ideally.
Is there some straightforward way to intercept I/O to a specific folder or virtual drive? If the answer is with EasyHook or a MiniFilter, does anyone have any samples? EasyHook in particular only has samples from the late-2000s and the API has changed since then. Thanks!

Looks like an XY problem. What you seem to want are reparse point handlers.
Your example of "writing a file to another location" is just a link, and those already exist. Implemented by a standard reparse point handler.
You don't specify exactly what else you want to do, but similar things can be done by custom reparse point handlers. In short, a reparse point is a small bit of data in place of a file, which (1) specifies which handler should be called, and (2) provides custom data to that handler. For instance, the actual location of the file. Since it's custom data, you can use any format you like.

Related

C# Monitor File Activity

I need to monitor a file for changes and see exactly where it has been modified.
It seems like I can't use FileSystemWatcher as I only get notified that a file has been modified but I can't know exactly what changed, and storing copies of the file to do a diff after the event is raised is not feasible since the file is really big.
I would like to implement something like what SysInternals have on their Process Monitor software, that tells us, for a WriteFile event, the modified part of the file given an offset and length.
I read that there is a Windows API that does this, but I couldn't find anything on how or where to start implementing it on a .net 3.5 application.
From what I have investigated, the .NET platform provides this event for handling file change events. However, this alone will not let you know what part of the file has changed.
You will need to store somewhere a copy of the file that is compared to the file whenever it changes, and then update that copy when the comparison is done. This is a very basic solution and can get really inefficient if the file is too large.
Using the FileSystemWatcher you can subscribe to the changed event ChangedEvent
FileSystemEventArgs contains a property FullPath which can be passed in to FileInfo. This will give you some basic file information, which can be stored to a database for example. You can keep a history of the file changes this way.
If you need to compare the content of the files it is more challenging and the approach will be different depending on file type.

C# Win32 Fire event on file read

I want to be able to detect if a file is read by another process. For example, if a text editor open's a file, I want to have a function to be able to get the name of the file that was read.
I saw that you can use the FileSystemWatcher class in C# to watch a directory for file changes but they don't solve the problem, I saw these on a 6 year old thread.
Has anything new been added to C# or Win32's API since then to allow file open detection?
Indeed this is a very complex subject, you would need to work with a File System Filter Driver (https://msdn.microsoft.com/windows/hardware/drivers/ifs/index) very low level stuff which would be hard to implement, I think that at least in the .net world there is not an easy way to do this.

Send File Programmability in C#

How would you go about detecting, blocking, or just in general referring to the Send File operation you can do to any file/folder on Windows. What exactly is happening when a send file happens and is there any kind of built in programmability in .NET or is it something similar to how doing a move works(It gets deleted first and then created in the new location.)
I just want to know if there is any way to detect when a Send File happens or what windows does with the file/folder when a send file is executed.
If you are speaking of the "Send To" context menu when you right-click on a file/folder, that is the result of a shell extension handler. Pretty sure there's now way to intercept those:
Is there a Click Handler for Shell Extension
MS documentation on registering/creating your own handers is below:
http://msdn.microsoft.com/en-us/library/windows/desktop/cc144067%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/cc144110%28v=vs.85%29.aspx
I presume that if you select "Send To" and pick a folder/drive, then it would do a standard move or copy (depending on if it is the same drive or not). As mentioned by Alan, you can use a FileSystemWatcher to try and monitor specific files/directories, but be careful being over broad with what you are watching, because there are limitations on how fast FSW can receive events, meaning if you watch to much you will miss events. Another option if you absolutely must see the file move would be to hook into the Change Journal, but that gets really ugly.
If you want to stop someone from moving or copying a file, you would have to alter its permissions for read and/or modify to exclude the user.
There is a FileSystemWatcher class that may help you detect changes to the file system. Also, the File Class has a static method for Move and other file operations. You may look into the System.IO namespace
When you move a file, it doesn't usually get recreated and deleted (if they are on the same device). Usually its location is just modified. (hence it happens almost instantly even on large files)

C# Track copied files [duplicate]

This question already has answers here:
C# : file copy notifying [closed]
(2 answers)
Closed 9 years ago.
I am trying to keep track of files that are copied by users and other applications.
The FileSystemWatch only has events for Changed, Created, Deleted, Disposed, Error, and Renamed.
It doesn't fire an event when a file is accessed by the copy function or where the new file is being copied to.
Is there a method for monitoring the copy event/function of windows?
I don't know of any way using C#.
You can do this if you are willing to write a File System Filter Driver. [Definitely expert territory, as there is scope for corrupting files and/or bringing down your system]
A file system filter driver intercepts requests targeted at a file
system or another file system filter driver. By intercepting the
request before it reaches its intended target, the filter driver can
extend or replace functionality provided by the original target of the
request. Examples of file system filter drivers include anti-virus
filters, backup agents, and encryption products. To develop file
systems and file system filter drivers, use the IFS (Installable File
System) Kit, which is provided with the Windows Driver Kit (WDK).
You are doing the right thing with FileSystemWatcher. Windows does not have any built-in mechanism for reporting copies reliably.
You could hook the OS copy routine, but this won't guarantee you good results: applications are free to implement their own copy by just opening the source and destination files and copying the bytes over.
Renaming is different because a rename done by the OS cannot be easily mimicked through other means, so you will catch all renames with the FileSystemWatcher. Note that moving between drives is more like copy: you won't get a Renamed notification, but a Created and a Deleted instead.
So if you really really need to notice a file getting copied, my suggested approach is this:
Hook the CloseFile calls, in addition to the FileSystemWatcher.
Whenever a file gets closed, it could be because it's the source or target of a copy / cross-drive move. Check its size.
If you find two closed files with the same size within a reasonably short period of time, compare the content. Pretty resource-intensive, but the only reliable way to do this.
You can use Auditing file and folder access feature of Windows which writes an event log entry and you can setup programs to start when such an event occurs
I can't think of any good way.
For each newly created file, you need to check if there is an exact duplicate (perhaps with a different name) anywhere on the filesystem. You could obviously do this brute-force, but the solution would be very inelegant, slow and brittle!

Responding to interactions with files in C#?

I want to write a program that will encrypt an entire folder and it's sub-folders, I have no problem doing this but I would like to make the entire encryption process rather transparent by letting a user double click it and have it open as if it weren't encrypted, say if it were a picture or a word document and it'd open in it's respective application.
How can a running program of mine become notified about the opening of a target file, stop the file from opening, do what it needs to do (decrypt), followed by running the resulting decrypted file.
How can I watch a file and do this in C#? Can I watch for other interactions like the user copying a watched file (since it won't be in a watched folder, it should be decrypted i.e. it's dragged to a USB device), or for deleting a watched file (say if I want to shred a file before deletion)?
P.S. The FileSystemWatcher doesn't quite meet my needs. EDIT: What I mean is that FileSystemWatcher will tell me when a file is being opened, deleted and all those events, but it won't let me step in real quick, decrypt the file, and hand it back to the process that normally opens that file.
You can rename files, add them your own extension, like thepicture.jpg.encrypted. Set your program as a default program for this extension and handle opening them
It's impossible in C#. the bare minimum would need you to use user-mode hooks on NtCreateFile, NtOpenFile, etc. You can't achieve that in C#. That wouldn't even work properly due to kernel-mode code which may try to access your files. The proper way of doing this would be to write a I/O minifilter (in C of course).
EDIT: If you're really desperate, try EasyHook - it allows you to hook functions from C#. I haven't tried it though, and it does seem risky hooking vital functions like NtCreateFile. Plus you need a fair bit of Native API knowledge.
Are you using Windows? If so, why not use the built-in BitLocker?
See this link:
BitLocker drive encryption
If you are thinking about a competitive application to BitLocker, add a comment, as I can point you in that direction as well.
Instead of trying to reinvent the wheel, use NTFS file encryption. You can encrypt single files or entire folders or drives. Plus it's completely transparent to the user and does exactly what you asks (e.g. automatically decrypt when copying to a UBS drive, etc). Just use System.IO.File.Encrypt(string) - there couldn't be anything easier.
You can't do this from usermode.
Unfortunately the only way to do this is to write a minifilter driver. Minifilter drivers allow you to intercept IO requests to files, you can then encrypt/decrypt the files you care about on the fly.
It sounds simple, but encryption minifilter drivers are very, very, difficult to get right. You will have to end up shadowing file objects which is a real challenge. Check with www.osr.com, they have a ton of information on doing exactly what you want to do.
If you choose to go this route I would recommend getting a copy of VMWare Workstation and download VirtualKD. It will let you debug at near fire-wire speeds into a VM. I would start with x64 Win7 and get remote shares working first.

Categories