如何捕获文件创建和负责的调用者

时间:2009-05-26 12:37:09

标签: c++ winapi file debugging creation

我们正在使用第三方库来渲染3d。在此库中,有一个“内存跟踪器”功能,可以跟踪库在执行期间分配和释放的所有内存。这是一个很好的功能,因为它有助于确定例如内存泄漏。

通过调用此库中的某个函数,将在该进程的当前工作目录中生成一个日志文件。最近我注意到这个文件显示在几个不同的地方,所以我的第一个想法当然是始终将当前工作目录设置为我希望日志显示的文件夹,这样可以正常工作。

然而,事实证明,该文件仍然在各个地方创建,而程序没有调用上述功能。因此,文件必须以某种方式由图书馆在未经我同意的情况下创建。该库的创建者表示引擎从不在内部调用此方法。

所以,为了证明他是错的(或者证明自己是愚蠢的(虽然不会是第一次)),我需要一种方法来准确捕捉这个文件的创建时间。 FindFirstChangeNotification()不会这样做,因为这只会向我提供某些文件夹中发生的事情的信息。理想情况下,我希望(在进程中或进程外)拦截发生这种情况并以某种方式注入进程异常(例如使WinDbg捕获这个),所以我通过callstack获取我想要的信息。

欢迎任何建议。

干杯!

2 个答案:

答案 0 :(得分:3)

你可以尝试:

  1. 使用FileMonProcess Explorer等工具,它们可能足以跟踪它。
  2. 使用挂钩库并使用您自己的函数替换CreateFile(或更多功能,如果需要)。我对Detours有很好的经验,它有一些非常好的例子,你可以直接使用。

答案 1 :(得分:2)

您需要使用自定义CreateFile创建注入DLL,如下所示:

/** 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方法来进行数据传输。