ralphtheninja
ralphtheninja

Reputation: 133168

How to catch file creation and the responsible caller

We are using a third part library to render 3d. In this library there is a "memory tracker" functionality that keeps track of all memory the library has allocated and freed during execution. This is a nice feature, since it helps by determining e.g. memory leaks.

By calling a certain function in this library a log file is generated in the current working directory of the process. Lately I've noticed that this file shows up in several different places, so my first thought was of course to always set the current working directory to the folder I want the log to show up in, and this works fine.

However, it turns out that this file is still created in various places without above mentioned 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, in order to prove him wrong (alternatively proving myself to be stupid (won't be the first time though)), I need a way to catch exactly when this file is created. FindFirstChangeNotification() will not do, since this will only provide me with information that something happened in some folder. Ideally I'd like to (either in process or out of process) intercept when this happens and somehow inject a process exception (e.g. make WinDbg catch this), so I through the callstack get the information I want.

Any suggestions are welcome.

Cheers!

Upvotes: 0

Views: 307

Answers (2)

nhaa123
nhaa123

Reputation: 9808

You need to create injection DLL with 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'll also need to benefit from Detours as well:

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 leave the rest for your exercise. This is just a point of direction. You need to find a suitable IPC method as well, for data transmitting.

Upvotes: 2

Idan K
Idan K

Reputation: 20901

You could try:

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

Upvotes: 3

Related Questions