How to detect when a file is checked for in a directory?

936 views Asked by At

I want to be able to programmatically (C#) detect when a program attempts to load (or otherwise access) a non-existent DLL from a directory that I control/own on Windows.

I can manually accomplish this using Sysinternals Process Monitor (ProcMon). For example, using the filters shown below, I am able to detect an attempt by the ClientPrj.exe program, to load a dll (GetEvenOdd.dll) from a directory I control (C:\MyDirectory);

Detect LoadLibrary using Procmon

How do I accomplish something similar programmatically?

My attempts thus far have involved manually enabling Windows Auditing on the folder, running the program, and then checking the Windows Event log for any Audit entries, but no new entries appear in the event log related to this folder.

Note, I am not looking to exactly replicate procmon, I simply want to detect when a file (in this case a DLL) is attempted to be loaded from the directory I control.


Side note; It's unclear to me why ProcMon lists the attempt to load the DLL as a "CreateFile" operation, because the "ClientPrj.exe" program is simply trying to Load the DLL (in C++ the "ClientPrj.exe" program is using the the LoadLibrary method to load the DLL).

2

There are 2 answers

0
TheGeneral On BEST ANSWER

I thinks is pretty safe to answer this question,

I want to be able to programmatically (C#) detect when a program attempts to load (or otherwise access) a non-existent DLL from a directory that I control/own on Windows.

There is really only one reliable way to achieve this, and its really not for the faint-or-heart.

I can manually accomplish this using Sysinternals Process Monitor (ProcMon).

ProcMon is a very complex application and makes use of all sorts of black magic in Kernel Mode to achieve what it does


DLL injection

In computer programming, DLL injection is a technique used for running code within the address space of another process by forcing it to load a dynamic-link library.1 DLL injection is often used by external programs to influence the behavior of another program in a way its authors did not anticipate or intend.1[2][3] For example, the injected code could hook system function calls,[4][5] or read the contents of password textboxes, which cannot be done the usual way.[6] A program used to inject arbitrary code into arbitrary processes is called a DLL injector.

The premise is exceedingly simple, and its a well used technique to do various things.

Basically, you need to inject a DLL into the program address space. The best known and most often used method is "Import Table Patching". Each win32 module (application/DLL) has a so-called "import table", which is basically a list of all APIs, which this module calls. Patching this import table is a quite easy job and works very nicely.

Another more robust method is, you can also directly manipulate the API's binary code in memory. The most often used method is to overwrite the first 5 bytes of the API code with a JMP instruction, which then jumps to your callback function.

In your case you want to Find LoadLibrary in your target application, JMP to a proxy where you can monitor the libraries loaded and also the results of the call, then pass back the results to the original caller.

This is pretty intense stuff, however it is more common that what you think. There are libraries written that Use Drivers that work in Kernel Mode Which work for 64bit and 32Bit applications that take care off all the hard work, you basically just give it a scope a dll and a signature of the apis you want to hook and write a proxy. and it will take care of the rest. At that point you can IPC the results anywhere you like.

Your first problem is setting a hook before it loads your target lib. However once again this has all be done for you. take a look at http://help.madshi.net/madCodeHook.htm

The onyl down side here, is it has to be done with a traditional DLL and not in .net

Anyway good luck

2
DRapp On

I can only assume that you have not even tried. I just did

private FileSystemWatcher fsWatcher;

public void SetupWatcher()
{
   fsWatcher = new FileSystemWatcher();
   fsWatcher.Path = @"C:\SomePath\SomeSubFolder\";
   fsWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
            | NotifyFilters.FileName | NotifyFilters.DirectoryName;
   fsWatcher.Filter = "*.*";
   fsWatcher.Changed += FsWatcher_Changed;
   fsWatcher.EnableRaisingEvents = true;

   System.IO.File.WriteAllText(fsWatcher.Path + "MyFile.txt", "testing" );
}

private void FsWatcher_Changed(object sender, FileSystemEventArgs e)
{
   var msg = "Action " + e.ChangeType + "\r\n"
           + "FullPath " + e.FullPath + "\r\n"
           + "Just File Name " + e.Name;

   MessageBox.Show(msg);
}

So, even though my "MyFile.txt" does not exist in the folder, as soon as I try to write to it, create, etc, the FsWatcher_Changed event handler is called. I can then check the change type, path of the file, just file name, etc. From that you can detect and confirm if the file name is what you expect (or not) and act on it as needed.

Feedback from comment...

As per from another program... If I am running my program with the above sample SystemFileWatcher and am listening to the entire folder in question.. Then I go to another applications (even ex: Word, Excel, whatever) and try to create a file in this folder, it will still get caught.

If another program is trying to open a file that does not exist, that program would fail out anyhow. Why would you necessarily care if another program fails validating a file to open that does not exist. That is a problem of the other program?