views:

461

answers:

2

I have a small command-line application written in C that acts as a wrapper/launcher for other programs (think: xargs). The application is written to compile on FreeBSD/Linux (via fork()/exec()) and Windows (CreateProcess()). In addition to being able to intercept, inject, or otherwise manipulate the command-line arguments for the child application, I was wondering if there is an easy way to intercept the child program's filesystem activity (or it's children, and so forth). I'm mainly interested in just the filenames accessed for either read or write, but not the contents of said files, and would like the interception to be as lightweight as possible.

In googling some relevant keywords from above, it seems there are many ways to do this in Win32. From file system filter drivers to tampering with PE import table headers. None of these seem trivial or something I could self-contain within my wrapper program's executable (e.g. most would require extra DLLs or driver files alongside the main executable.) Also, I'd like this to work on Windows XP through 7, if possible, without having to hack around UAC or other platform deltas. It's my child process, so I figure I should be able to securely monitor its activity :)

On Linux, there is inotify(), but it monitors general filesystem access without regard to ONLY my child process/es. Same thing goes for FreeBSD's kqueue(). These also break down in SMP cases where multiple instances of the wrapper might be running different programs, and each needs to disambiguate their own child's filesystem activity from one another.

I'd certainly appreciate any suggestions that the SO community might have to offer.

+2  A: 

The only suggestion I would make is to use strace (trace system calls and signals), though this is more of a debugging tool, and does affect the performance of the process being traced

strace -f -e trace=file -o <output-file> <cmd-line>

-f - follow forks
-e trace=file - will output system calls related to the file-system
-o <output-file>

IMHO - if you get familiar with strace, it is always a useful tool to have in the armory.

Beano
Thank you, Beano. I've used strace, but was unaware of the -e trace=file shortcut ... very handy. Unfortunately, the performance penalty is a bit high, as it uses ptrace(2) under the hood.
Optigrab
A: 

Write a "interposer" library that hooks your fopen and set LD_PRELOAD environment variable for all child processes. This works with dynamically linked libraries thou.

Example of how to do this can be found here: http://developers.sun.com/solaris/articles/lib_interposers.html and http://lists.debian.org/debian-powerpc/2004/11/msg00039.html shows a partial implementation for fopen() interposer..

rasjani
If you want to go this route, you'd probably be better off intercepting the system calls that access the file system. open(), creat(), chmod(), exec*(). There may be others.
Keith Smith
^ true, allthou writing such wrapper with implementations for open(), fopen(), fdopen(), freopen() should cover quite a lot of cases.
rasjani
This approach seems to be the simplest, with the only downside being that I need to have a separate 'interceptor' shared library file in addition to just my executable. Is there a mechanism equivalent to LD_PRELOAD on Win32 platforms?
Optigrab
Optigrab: Im not familar with windows development but found this wikipedia article which describes 4 ways to archive the same: http://en.wikipedia.org/wiki/DLL_injection
rasjani
Thank you all for the pointers. On *nix, I'm successfully using LD_PRELOAD, and on Win32, I found a great article on DLL injection here: http://www.codeproject.com/KB/threads/completeinject.aspxThe only downside of this approach is needing the extra .so/.dll file living alongside my executable. I suppose I could auto-extract it, use it , and delete it from inside my executable, but I'll leave that for another day.
Optigrab
I just want to add one thing. This approach is not entirely secure against tampering. Meaning that if child process actively tries to avoid your attention/limits it can do so.
Stan