How to catch file creation and responsible subscriber

We are using 3rd part library for 3d rendering. This library has a "memory tracking" function that keeps track of all the memory that the library has allocated and freed during runtime. This is a nice feature as it helps by detecting, for example, a memory leak.

By calling a specific function in this library, a log file is generated in the current working directory of the process. Lately I've noticed that this file appears in several different places, so my first thought was, of course, to always set the current working directory to the folder where I want the log to be displayed, and that works great.

However, it turns out that this file is still being created in various places without the aforementioned function ever being called by the program. Hence, the file must somehow be created by the library without my consent. The creator of this library says that the engine never calls this method internally.

So, to prove that he is wrong (alternatively, proving that I am stupid (not the first time)), I need a way to catch when this file is created. FindFirstChangeNotification () will not do as it will only give me information that something happened in some folder. Ideally, I would like (in-process or out-of-process) to intercept when this happens and somehow inject a process exception (for example, force WinDbg to catch this), so I get the information I need through the callstack.

Any suggestions are greatly appreciated.

Hooray!

0


a source to share


2 answers


You can try:



  • Use a tool like FileMon or Process Explorer , they might be enough to track it down.
  • Use the library binding and replace CreateFile (or more functions if you need) with your own function. I've had a good experience with Detours , he has some really good examples that you could use right out of the box.
+3


a source


You need to create an injection DLL with a custom CreateFile, something like this:

/** 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;
}
      

However, this is not enough. You will also need to use 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;
}
      

I'll leave the rest for your exercise. This is just a direction point. You also need to find a suitable IPC method for transferring data.

+2


a source







All Articles