Как определить, когда файл проверяется в каталоге?

Я хочу иметь возможность программно (C#) определять, когда программа пытается загрузить (или иным образом получить доступ) несуществующую DLL из каталога, которым я управляю / владею в Windows.

Я могу сделать это вручную, используя Sysinternals Process Monitor (ProcMon). Например, используя фильтры, показанные ниже, я могу обнаружить попытку программы ClientPrj.exe загрузить dll (GetEvenOdd.dll) из каталога, которым я управляю (C:\MyDirectory);

Определить LoadLibrary с помощью Procmon

Как мне сделать что-то подобное программно?

До сих пор мои попытки заключались в том, чтобы вручную включить аудит Windows для этой папки, запустить программу, а затем проверить журнал событий Windows на наличие записей аудита, но в журнале событий, связанных с этой папкой, новые записи не появляются.

Обратите внимание, я не ищу точной репликации procmon, я просто хочу определить, когда файл (в данном случае DLL) пытается быть загружен из каталога, которым я управляю.


Примечание; Мне непонятно, почему ProcMon перечисляет попытку загрузки DLL как операцию "CreateFile", потому что программа "ClientPrj.exe" просто пытается загрузить DLL (в C++ программа "ClientPrj.exe" использует LoadLibrary способ загрузки DLL).

2 ответа

Я думаю, что довольно безопасно ответить на этот вопрос,

Я хочу иметь возможность программно (C#) определять, когда программа пытается загрузить (или иным образом получить доступ) несуществующую DLL из каталога, которым я управляю / владею в Windows.

На самом деле есть только один надежный способ достичь этого, и он действительно не для слабонервных.

Я могу сделать это вручную, используя Sysinternals Process Monitor (ProcMon).

ProcMon - очень сложное приложение, использующее все виды черной магии в режиме ядра для достижения цели.


DLL инъекция

В компьютерном программировании внедрение DLL - это метод, используемый для запуска кода в адресном пространстве другого процесса, заставляя его загружать динамически подключаемую библиотеку. Внедрение DLL часто используется внешними программами, чтобы влиять на поведение другой программы так, как ее авторы не ожидали и не предполагали. 1 [2] [3] Например, введенный код может перехватывать вызовы системных функций,[4][5] или читать содержимое текстовых полей пароля, что не может быть выполнено обычным способом.[6] Программа, используемая для внедрения произвольного кода в произвольные процессы, называется DLL-инжектором.

Предпосылка очень проста, и это хорошо используемая техника, чтобы делать различные вещи.

По сути, вам нужно внедрить DLL в адресное пространство программы. Наиболее известным и наиболее часто используемым методом является "Импортирование таблицы импорта". Каждый модуль win32 (приложение /DLL) имеет так называемую "таблицу импорта", которая представляет собой список всех API, которые вызывает этот модуль. Исправление этой таблицы импорта является довольно простой работой и работает очень хорошо.

Другой более надежный метод заключается в том, что вы также можете напрямую манипулировать двоичным кодом API в памяти. Наиболее часто используемый метод - это перезапись первых 5 байтов кода API инструкцией JMP, которая затем переходит к вашей функции обратного вызова.

В вашем случае вы хотите найти LoadLibrary в вашем целевом приложении, JMP на прокси, где вы можете отслеживать загруженные библиотеки, а также результаты вызова, а затем передавать результаты исходному вызывающему.

Это довольно напряженная штука, но чаще всего то, что вы думаете. Существуют библиотеки, в которых используются драйверы, работающие в режиме ядра, которые работают для 64-битных и 32-битных приложений, выполняющих всю тяжелую работу, в основном вы просто задаете для этого dll и сигнатуру apis, которую хотите подключить и написать прокси. и он позаботится об остальном. На этом этапе вы можете IPC результаты где угодно.

Ваша первая проблема - установка хука перед загрузкой вашей целевой библиотеки. Однако еще раз это все сделано для вас. взгляните на http://help.madshi.net/madCodeHook.htm

Оборотная сторона здесь, это должно быть сделано с традиционной DLL, а не в.net

В любом случае удачи

Я могу только предположить, что вы даже не пытались. я только что сделал

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);
}

Итак, хотя мой "MyFile.txt" не существует в папке, как только я пытаюсь записать в него, создать и т. Д., Вызывается обработчик события FsWatcher_Changed. Затем я могу проверить тип изменения, путь к файлу, просто имя файла и т. Д. Из этого вы можете определить и подтвердить, соответствует ли имя файла тому, что вы ожидаете (или нет), и действовать в соответствии с ним.

Отзыв от комментария...

Согласно другой программе... Если я запускаю свою программу с приведенным выше примером SystemFileWatcher и слушаю всю папку, о которой идет речь, то я перехожу к другим приложениям (даже к примеру: Word, Excel и т. Д.) И пытаюсь создать файл в этой папке, он все равно будет пойман.

Если другая программа пытается открыть файл, который не существует, эта программа все равно потерпит неудачу. Почему вас должно волновать, что другой программе не удается проверить файл, который не существует. Это проблема другой программы?

Другие вопросы по тегам