我需要开发一个应用程序来监视并可能过滤(拒绝调用)文件操作。
似乎开发微过滤器是“标准”解决方案。另一种可能的方法是使用 API 挂钩。
这些是相关的解决方案吗?(我在某些地方读到 API 挂钩可能不适合 - 但没有给出解释)
还有其他选择吗?
我需要开发一个应用程序来监视并可能过滤(拒绝调用)文件操作。
似乎开发微过滤器是“标准”解决方案。另一种可能的方法是使用 API 挂钩。
这些是相关的解决方案吗?(我在某些地方读到 API 挂钩可能不适合 - 但没有给出解释)
还有其他选择吗?
微软基本上不支持 API 挂钩(至少在内核空间中)。在 x64(从 Vista 和更高版本开始)上,如果它检测到 SSDT 挂钩或系统关键组件的任何更改,patchguard 通常会杀死机器。API 挂钩很难在系统范围内获得,因为 Windows 使用的同步原语不会导出,所以即使您设法挂钩代码,也不能保证机器不会因为 EIP 的时髦值而崩溃在给定的时刻(这在您卸载已挂钩函数的驱动程序时尤其有效)。
最好的选择可能是这样做 - 不使用微过滤器驱动程序是尝试并直接连接内存内核对象。您可能想查看每个对象窗口具有的 OBJECT_TYPE_INITIALIZER定义结构(文件、事件、端口等 - 谷歌周围查看它们)作为其成员。您对 *Procedure 函数指针特别感兴趣。
这一切都归结为您想要/需要完成的事情。
如果您只需要文件操作(在内核级别,文件打开/文件关闭),并且您需要它在系统范围内而不是使用微过滤器。这是一条漫长、乏味且耗时的道路,但更安全(查看 Sysinternals procmon 以了解使用此方法可以获得什么)。
如果您需要更多特定于应用程序的控件,或者您想控制 WINAPI 级别,请使用 API 挂钩。它更容易开发,但有很多“地雷”在你的脸上炸开(看看 EasyHook,它用最少的工作做得很好)。
祝你好运!
如果您从安全角度阻止用户访问某些资源(文件),那么正确的方法是使用微过滤器。这是因为这是您确定用户无法访问已过滤资源的唯一方法。
如果您使用 API 挂钩,您可以拦截 kernel32.dll(CreateFileW、FindFirstFile 等)的调用,但攻击者可以使用 Native API (ntdll.dl)。当然,您可以在 Native 级别进行拦截(因为它没有记录,所以更加困难),但攻击者可以在内核切换级别使用不同的 API。在那个级别上,它不便于挂钩。使用 API 钩子来阻止创造性的攻击者访问资源几乎是不可能的,这就是为什么不建议将它用于安全软件的原因。
在我看来,API 挂钩是一个很好的监控选择。如果您想查看应用程序在做什么,使用 API 挂钩非常好,因为您可以拦截比内核模式更高级别的函数。
如果你可以在没有钩子的情况下完成任务 - 去做吧。因为挂钩不是开发应用程序的受支持方式。有很多陷阱,防病毒软件会将您的应用程序视为更危险。此外,您可能会遇到新/旧版本操作系统的问题。
但是考虑到用户模式代码比内核模式要容易得多。因此,如果用户模式挂钩可以满足您的要求,那么您可以考虑它们。
我通过邮件收到了后续问题,所以我在这里添加了我们使用的解决方案
该项目在它停止运行之前被取消,但我们评估了一个允许使用用户空间代码编写内核过滤器的产品 ( Eldos CallbackFilter )。
该产品具有通用内核驱动程序,可与定义过滤逻辑的用户空间代码进行通信。
我不得不反驳LordDoskias,因为OBJECT_TYPE_INITIALIZER不是记录在案的对象,它可以、已经并且将随着操作系统补丁和更新而改变。不要接近这个问题,因为它只会导致更多问题而不会解决任何问题。更不用说如果你修改系统结构会蓝屏系统的补丁保护。如果你想限制对文件的访问,除了使用微过滤器之外别无他法。这里有几个微软示例您可以从中汲取灵感,并学习以正确且受支持的方式实施您的驱动程序。最后,更重要的是,认为你可以通过钩子技术阻止你想要的一切是虚幻的,我只给你一个例子:映射文件。这是一个涉及记事本的场景,它使用映射文件将其数据写入磁盘。
这就是你在使用 hooking 时所缺少的。这只是一种情况。他们有很多,所以请以正确的方式做事。如果您使用微过滤器,情况会如何变化?您当然也会捕获 CreateFile、CreateFileMapping(检查FltAcquireForSectionSynchronization回调),然后从微过滤器中,您将在 Write 调度回调中看到来自内存管理器的所有 PAGING_WRITE(参见IoGetTopLevelIrp())。
祝你好运。