Question

I would like to write a C++ function, on Microsoft Windows, that spawns a process and returns, in addition to the process's termination status, a list of all the files the process read or wrote. It should not require any cooperation from the spawned application.

For example, if the program spawned is the Visual Studio C++ compiler, the function would produce a list containing the source file the compiler opened, all header files it read, and the .OBJ file it created. If it also contained things like .DLL files the program contained, that would be fine. But again, it should work regardless of the program spawned; the compiler is just an example.

A twist: if the process creates subprocesses, I need to monitor their file accesses as well.

A second twist: if the process tries to open a file, I would like to be able to make it wait until I can create that file—and only then let it resume and open the file. (I think this rules out ETW.)

I know this probably sounds like an ingredient for some horrible kludge. But if I can get this working, the end result will be really cool.

Was it helpful?

Solution

A second twist: if the process tries to open a file, I would like to be able to make it wait until I can create that file—and only then let it resume and open the file

You just put yourself into Hack City with that requirement - you're right that ETW would've been a far easier solution, but it also has no way to block the file call.

Basically, here's what you're going to have to do:

  1. Create the process suspended
  2. Create two named pipes in opposite directions whose names are well known (perhaps containing the PID of the process)
  3. Hook LoadModule, and the hook will watch for Kernel32 to get loaded
  4. When Kernel32 gets loaded, hook CreateFileW and CreateFileA - also hook CreateProcessEx and ShellExecute
  5. When your CreateFile hook hits, you write the name to one of the named pipes, then execute a ReadFile on the other one until the parent process signals you to continue.
  6. When your CreateProcessEx hook hits, you get to do the same process all over again from inside the current process (remember that you can't have the parent process do the CreateProcess'ing because it'll mess up inherited handles).
  7. Start the child process.

Keep in mind that you'll be injecting code and making fixups to an in-memory image that may be a different bitness than yours (i.e. your app is 64-bit, but it's starting a 32-bit process), so you'll have to have both x86 and amd64 versions of your shim code to inject. I hope by writing this lengthy diatribe you have convinced yourself that this is actually an awful idea that is very difficult to get right and that people who hook Win32 functions make Windows OS developers sad.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top