jacereda / fsatrace

Filesystem access tracer
ISC License
81 stars 12 forks source link

Doesn't trace execution on Windows #19

Closed ndmitchell closed 5 years ago

ndmitchell commented 5 years ago

On Windows, if I create a binary Main.exe (in Haskell, but not sure that matters) and then do:

fsatrace rwmdq output.txt -- Main.exe

I don't get Main.exe as a file that is ready. Furthermore, doing cmd /c Main.exe as the command line doesn't get either cmd or Main as the detected binaries. It seems that the binary being run doesn't get a "Read" entry?

jacereda commented 5 years ago

Do you get any file op reported? Is the executable 64 or 32 bit?

Here is the list of hooks, do you know if the haskell runtime or that concrete executable is using something not listed there?

https://github.com/jacereda/fsatrace/blob/master/src/win/hooks.c

ndmitchell commented 5 years ago

64 bit all the way.

I reproduced using C, to simplify things. Given the files:

/* execer.c */
#include <unistd.h>
#include <stdio.h>

void main(){
  printf("Pre exec\n");
  system("hello-world.exe");
  printf("Post exec\n");
}
/* hello-world.c */
#include <stdio.h>

void main() {
  printf("Hello world\n");
}

Which I compiled into execer.exe and hello-world.exe using gcc.

When running fsatrace ... - execer I would like to see execer.exe and hello-world.exe both appear as read. Trying some tracing and playing around, I have some (unfounded and unproven) ideas about why neither appears (only r|C:\Windows\Globalization\Sorting\SortDefault.nls shows up).

  1. Theory for execer.exe is that it gets loaded before your dll is included, so the initial load and any dlls won't see it. If so, you can just fake an emit after CreateProcessW. I don't know if any DLL's loaded during startup also happen before then?
  2. Theory for hello-world.exe is that it gets loaded via a call to NtOpenProcess, which loads the file in kernel space. Adding a hook for that I see the call go by. I tried grabbing the oa->ObjectName but that was a null pointer.

I'm not sure if either of my theories helps find dll's that are loaded. I do note that Process Monitor from SysInternals does manage to detect the CreateFile calls associated with the exe, but don't know how relevant that is.

jacereda commented 5 years ago

I guess we can live without execer.exe being recorded.

Hooking NtOpenProcess might be a bit trickier than the rest. You can try GetModuleFilenameW() on the returned handle, maybe that will yield a valid name.

Unfortunately I don't have any Windows box right now, I'd need to borrow one at work or something.

ndmitchell commented 5 years ago

I found a simpler way - just list the loaded dlls when we get loaded. Given you are Windows free, I opened a PR #20