Как определить, когда файл проверяется в каталоге? - PullRequest
0 голосов
/ 02 октября 2018

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

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

Detect LoadLibrary using Procmon

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

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

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


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

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

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

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 и т. д.) и попытайтесь создать файл в этой папке, он все равно будет пойман.

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

0 голосов
/ 02 октября 2018

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

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

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

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

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


внедрение DLL

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

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

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

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

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

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

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

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

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

...