When the three bears got back to their lodge they were eager to find out who touched all their stuff. We were recently in a similar position, our application was too slow, we suspected that we were accessing the file system too much and wanted to find out who was to blame. A short ProcMon session showed we were right but even with the view stack functionality it was a bit difficult to understand what each file access was doing and whether it was justified.
We wanted a breakpoint that will fire every time a file is read whether it’s from .NET or native C++ code and the following breakpoint fit the bill.
When reading a file you must first get a file handle which is done with the Win32 CreateFile function, since all current versions of Windows use wide characters for strings CreateFile is a macro that points at the
CreateFileW function. As you can see from the documentation this function accepts 7 arguments each is 4 bytes big meaning that a total of 28 bytes are passed to it. Because Win32 functions use the
__stdcall calling convention the symbol for this function is preceded by an underscore and followed by an at sign followed by the number of bytes passed on the stack.
Hence break at function: _CreateFileW@28
Now in order to break only when accessing files that concern us we add a condition. Look at the first parameter (lpFileName) which is at location esp+4 (right after the stack pointer) and treat it as a wchar_t*. Now call the wcsstr function from the C runtime to see if our file is being accessed (it will return
nullptr if the substring isn’t found).
I hope others find this breakpoint as useful as I did.