我想编写能够在进程(及其子进程)执行期间检测所有使用/创建/修改/删除的文件的软件。该进程还没有运行——用户提供了一个命令行,稍后将通过 bash 对其进行子处理,因此我们可以在执行之前和之后做一些事情,并控制命令运行的环境。
到目前为止,我已经想到了四种可能有用的方法:
- 解析命令行以识别提到的文件和目录。假设使用了所有明确提到的文件。检查创建/删除文件之前/之后的目录。MD5 现有文件之前/之后看到任何被修改。这适用于所有操作系统和环境,但显然有严重的限制(当命令是“./script.sh”时不起作用)
- 通过另一个进程运行该进程,例如 strace(用于 OSX 的 dtruss,并且有等效的 windows 程序),它侦听系统调用。解析输出文件以查找使用/修改/删除/创建的文件。优点是它比 MD5 方法更敏感,并且可以处理 script.sh。缺点是它非常特定于操作系统(dtruss 需要 root 权限,即使正在运行的进程不需要 - 工具的输出都不同)。如果有很多读/写操作,也可能会创建巨大的日志文件,并且肯定会减慢速度。
- 将与上述类似的东西集成到内核中。显然仍然是特定于操作系统的,但至少现在我们正在发号施令,为所有操作系统创建通用输出格式。不会创建巨大的日志文件,甚至可以在进程向文件请求第一个 read() 之后停止将系统调用挂钩到 read()。我认为这就是 inotify 工具正在做的事情,但我根本不熟悉它,也不熟悉内核编程!
- 使用 LD_PRELOAD 技巧运行进程(在 OSX 上称为 DYLD_INSERT_LIBRARIES,不确定它是否存在于 Windows 中),它基本上用我们自己的 open() 版本覆盖进程对 open() 的任何调用,该版本记录我们正在打开的内容。写入、读取等也是如此。它做起来非常简单,而且性能非常好,因为您本质上是在教进程记录自己。缺点是它只适用于动态链接的过程,我不知道动态/静态链接程序的普遍性。我什至不知道在执行之前是否有可能判断一个进程是动态链接还是静态链接(目的是默认使用此方法,但如果不可能,则退回到性能较差的方法)。
我需要帮助选择最佳路径。我已经实现了第一种方法,因为它很简单,并且为我提供了一种在日志后端 ( http://ac.gt/log ) 上工作的方法,但我确实需要升级到其他方法之一。你的建议将是无价的:)