Как отловить создание файла и ответственного абонента - PullRequest
0 голосов
/ 26 мая 2009

Мы используем библиотеку третьей части для рендеринга 3d. В этой библиотеке есть функция отслеживания памяти, которая отслеживает всю память, выделенную и освобожденную библиотекой во время выполнения. Это хорошая функция, так как она помогает, например, определить утечки памяти.

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

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

Итак, чтобы доказать, что он не прав (в качестве альтернативы можно доказать, что я глупый (хотя и не в первый раз)), мне нужен способ отловить, когда именно создается этот файл. FindFirstChangeNotification () не подойдет, поскольку это даст мне только информацию о том, что что-то произошло в какой-то папке. В идеале я хотел бы (в процессе или вне процесса) перехватывать, когда это происходит, и каким-то образом вводить исключение процесса (например, заставить WinDbg перехватить это), поэтому я через callstack получаю нужную информацию.

Любые предложения приветствуются.

Ура! * * 1013

Ответы [ 2 ]

3 голосов
/ 26 мая 2009

Вы можете попробовать:

  1. Используйте такой инструмент, как FileMon или Process Explorer , их может быть достаточно, чтобы отследить его.
  2. Используйте перехват библиотеки и замените CreateFile (или больше функций, если вам нужно) своей собственной функцией. У меня был хороший опыт работы с Detours , у него есть несколько действительно хороших примеров, которые можно использовать прямо из коробки.
2 голосов
/ 26 мая 2009

Вам нужно создать DLL для инъекций с пользовательским CreateFile, примерно так:

/** We'll create a custom version of the CreateFile (WinAPI).
  *
  *
  */
HANDLE WINAPI __CreateFile(LPCWSTR fileName,
                           DWORD desiredAccess,
                           DWORD shareMode,
                           LPSECURITY_ATTRIBUTES securityAttributes,
                           DWORD createDisp,
                           DWORD flags,
                           HANDLE tmp)
{
        // At very first, we shall call the original CreateFile.

        HANDLE file = Real_CreateFile(fileName,
                                      desiredAccess,
                                      shareMode,
                                      securityAttributes,
                                      createDisp,
                                      flags,
                                      tmp);

        /** Here, you can do whatever you wish with fileName and the handle, file.
          *
          * ...
          */

        return file;
}

Однако этого недостаточно. Вам также понадобится воспользоваться Detours:

BOOL APIENTRY DllMain(HANDLE module, DWORD reasonForCall, LPVOID reserved)
{
        switch (reasonForCall) {
                case DLL_PROCESS_ATTACH: {
                        if (::GetModuleHandle(L"blablabla.exe") == NULL) {
                                DetourTransactionBegin();
                                DetourUpdateThread(GetCurrentThread());
                                DetourAttach(&(PVOID &)Real_CreateFile, __CreateFile);
                                DetourTransactionCommit();
                }

                break;

                case DLL_THREAD_ATTACH: {
                }

                break;

                case DLL_THREAD_DETACH: {
                }

                break;

                case DLL_PROCESS_DETACH: {
                        if (::GetModuleHandle(L"blablabla.exe") == NULL) {
                                DetourTransactionBegin();
                                DetourUpdateThread(GetCurrentThread());
                                DetourDetach(&(PVOID&)Real_CreateFile, __CreateFile);
                                DetourTransactionCommit();
                        }
                }
    }

    return TRUE;
}

Я оставляю все остальное для вашего упражнения. Это просто точка направления. Вам также необходимо найти подходящий метод IPC для передачи данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...