首页
社区
课程
招聘
21
浅谈文件过滤原理与简单实现
发表于: 2021-11-5 16:29 32109

浅谈文件过滤原理与简单实现

2021-11-5 16:29
32109

在windows下,从XP到Win10,一共有两个文件系统,一个叫fastfat.sys,一个叫Ntfs.sys。

在WIN7和WIN10下,大家似乎不再使用fastfat.sys(也叫fast32)这个文件系统。

笔者也是这样,无论是新买的电脑还是U盘,或者移动盘,都给他刷成Ntfs。

Ntfs.sys 和Fastfat.sys 这两个windows下的文件系统,它们的目的不是存储文件,它们的目的是监控文件的所有操作。

比如打开文件,读取文件,写入文件,重命令文件,删除文件,新建文件\目录等,所有文件和目录的操作都被这两个文件系统驱动所监控。

Ntfs.sys 和Fastfat.sys 这两个windows下的文件系统,在完成监控的操作后,把实际的文件操作再发给磁盘的卷设备,由磁盘实现文件的操作。

总结:R3下的文件操作--->文件系统(Ntfs.sys或者Fastfat.sys)--->磁盘完成实际操作

既然了解它们的原理,那么我们就能对文件系统的驱动做手脚,来达成过滤的目的。

1.通过ObReferenceObject(“Ntfs.sys”)找到驱动对象,然后找到驱动对象下的MajorFunction数组,用我们写的函数替换掉数组的所有成员,同时,也需要替换驱动对象下的fastio成员。

总结:用HOOK的方式来实现文件过滤,兼容性的问题很大,即使用原子操作替换函数,稍有不慎,就会造成蓝屏。

2.通过ObReferenceObject(“Ntfs.sys”)找到驱动对象,然后用IoEnumerateDeviceObjectList()枚举所有设备对象,用设备挂靠的方式来实现Io过滤。

总结:相比HOOK的方式,设备挂靠是微软提供的接口,很安全,设备挂靠也是所有文件过滤驱动的首选方法。

实现文件过滤需要我们自己编写一个驱动。




第四步本来是注册一个文件系统通知回调,用来绑定所有文件系统的控制设备。(\FileSystem下的所有文件驱动)

但是笔者这里只想绑定Ntfs.sys所以注释掉。

这里是对 “5.挂靠Ntfs或者Fastfat驱动的所有设备对象” 的解释。

方法很简单:先找到Ntfs的驱动对象,然后遍历它的所有设备对象(控制设备和卷设备),然后逐个用生成的匿名对象来绑定,这样做的目的是:让发给Ntfs的文件系统的请求,先通过我们的驱动的Io和FastIo函数,然后由我们决定是否转发给Ntfs文件系统。这样就达成了我们过滤的目的。

需要注意的细节是:笔者在这里用了一个自定义的结构,放在了生成的设备对象的拓展上,这个目的是为了把请求下发给文件系统的设备对象,不然下发不了请求,整个操作系统的所有文件操作都不能实现。

fastio 是没有irp的快速请求,笔者并不想处理这些请求,让所有的Fastio函数,全部返回FALSE。

MajiorFunction中的函数,需要读者根据自己的需求,来编写属于自己的过滤函数。

在这里,笔者实现了一个读操作的函数,让所有读取文件的操作,打印出文件名,偏移量,读取的长度。

这里是编译后运行的效果:

至于其他的Io操作函数,全部下发即可。

在后续的文件过滤进阶上,不论是Sfilter过滤框架还是Minifilter过滤框架,它们的本质都是利用设备挂靠和MajorFunction函数来过滤,只是Minifilter利用了微软编写的文件过滤驱动FltMgr.sys提供的接口进行编程,忽略了IRP的种种细节。

在笔者的感受中,要处理IRP的种种细节太过于繁琐,无论是缓冲IO,还是直接IO,或者是Neithor IO,还有完成IRP的种种情况处理,需要先下发请求然后在完成函数过滤的,需要先下发请求然后在分发函数过滤的,需要先发下请求然后在工作队列过滤的等等等,简而言之 fuck Sfilter bro!

关于本文的利用,读者可以自行实现硬盘和分区的序列号HOOK,也可以通过文件特征实现对病毒的识别等

需要注意的是,所有文件过滤驱动不能处理文件内存映射的文件读写操作,内存映射的文件读写基于内存,文件过滤驱动并不能拦截到。

 
 
 
 
 
 
 
 
 
 
 
 
 
BOOLEAN FastIoCheckIfPossible(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PLARGE_INTEGER FileOffset,
    _In_ ULONG Length,
    _In_ BOOLEAN Wait,
    _In_ ULONG LockKey,
    _In_ BOOLEAN CheckForReadOperation,
    _Pre_notnull_
    _When_(return != FALSE, _Post_equal_to_(_Old_(IoStatus)))
    _When_(return == FALSE, _Post_valid_)
    PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;//效率可能会慢百分之十,加载可能会变慢
}
 
BOOLEAN FastIoRead(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PLARGE_INTEGER FileOffset,
    _In_ ULONG Length,
    _In_ BOOLEAN Wait,
    _In_ ULONG LockKey,
    _Out_ PVOID Buffer,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoWrite(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PLARGE_INTEGER FileOffset,
    _In_ ULONG Length,
    _In_ BOOLEAN Wait,
    _In_ ULONG LockKey,
    _In_ PVOID Buffer,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoQueryBasicInfo(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ BOOLEAN Wait,
    _Out_ PFILE_BASIC_INFORMATION Buffer,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoQueryStandardInfo(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ BOOLEAN Wait,
    _Out_ PFILE_STANDARD_INFORMATION Buffer,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoLock(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PLARGE_INTEGER FileOffset,
    _In_ PLARGE_INTEGER Length,
    _In_ PEPROCESS ProcessId,
    _In_ ULONG Key,
    _In_ BOOLEAN FailImmediately,
    _In_ BOOLEAN ExclusiveLock,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoUnlockSingle(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PLARGE_INTEGER FileOffset,
    _In_ PLARGE_INTEGER Length,
    _In_ PEPROCESS ProcessId,
    _In_ ULONG Key,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoUnlockAll(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PEPROCESS ProcessId,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoUnlockAllByKey(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PVOID ProcessId,
    _In_ ULONG Key,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoDeviceControl(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ BOOLEAN Wait,
    _In_opt_ PVOID InputBuffer,
    _In_ ULONG InputBufferLength,
    _Out_opt_ PVOID OutputBuffer,
    _In_ ULONG OutputBufferLength,
    _In_ ULONG IoControlCode,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
VOID AcquireFileForNtCreateSection(
    _In_ struct _FILE_OBJECT* FileObject
)
{
    return FALSE;
}
 
VOID ReleaseFileForNtCreateSection(
    _In_ struct _FILE_OBJECT* FileObject
)
{
    return FALSE;
}
 
VOID FastIoDetachDevice(
    _In_ struct _DEVICE_OBJECT* SourceDevice,
    _In_ struct _DEVICE_OBJECT* TargetDevice
)
{
    return FALSE;
}
 
BOOLEAN FastIoQueryNetworkOpenInfo(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ BOOLEAN Wait,
    _Out_ struct _FILE_NETWORK_OPEN_INFORMATION* Buffer,
    _Out_ struct _IO_STATUS_BLOCK* IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
//后面还有很多,一共有20多个fastio函数,全部返回FALSE即可
BOOLEAN FastIoCheckIfPossible(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PLARGE_INTEGER FileOffset,
    _In_ ULONG Length,
    _In_ BOOLEAN Wait,
    _In_ ULONG LockKey,
    _In_ BOOLEAN CheckForReadOperation,
    _Pre_notnull_
    _When_(return != FALSE, _Post_equal_to_(_Old_(IoStatus)))
    _When_(return == FALSE, _Post_valid_)
    PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;//效率可能会慢百分之十,加载可能会变慢
}
 
BOOLEAN FastIoRead(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PLARGE_INTEGER FileOffset,
    _In_ ULONG Length,
    _In_ BOOLEAN Wait,
    _In_ ULONG LockKey,
    _Out_ PVOID Buffer,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoWrite(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ PLARGE_INTEGER FileOffset,
    _In_ ULONG Length,
    _In_ BOOLEAN Wait,
    _In_ ULONG LockKey,
    _In_ PVOID Buffer,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoQueryBasicInfo(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ BOOLEAN Wait,
    _Out_ PFILE_BASIC_INFORMATION Buffer,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}
 
BOOLEAN FastIoQueryStandardInfo(
    _In_ struct _FILE_OBJECT* FileObject,
    _In_ BOOLEAN Wait,
    _Out_ PFILE_STANDARD_INFORMATION Buffer,
    _Out_ PIO_STATUS_BLOCK IoStatus,
    _In_ struct _DEVICE_OBJECT* DeviceObject
)
{
    return FALSE;
}

[注意]看雪招聘,专注安全领域的专业人才平台!

上传的附件:
收藏
免费 21
支持
分享
赞赏记录
参与人
雪币
留言
时间
東陽不列山
感谢你的贡献,论坛因你而更加精彩!
2025-4-10 02:57
一路南寻
感谢你的贡献,论坛因你而更加精彩!
2025-3-8 02:58
心游尘世外
为你点赞!
2024-11-24 01:36
shishichen
为你点赞~
2024-3-7 14:52
mb_nbakwvoe
为你点赞~
2023-3-31 16:00
伟叔叔
为你点赞~
2023-3-18 05:33
大道在我
为你点赞~
2023-3-3 15:46
一个懵懂的SB
为你点赞~
2023-2-28 17:31
Grav1ty
为你点赞~
2023-2-15 03:08
PLEBFE
为你点赞~
2022-7-30 06:20
飘零丶
为你点赞~
2022-7-19 17:01
Anowhere
为你点赞~
2021-12-8 20:42
谖草
为你点赞~
2021-11-9 14:28
卑鄙兔
为你点赞~
2021-11-5 16:58
学技术打豆豆
为你点赞~
2021-11-5 16:52
dz默契
为你点赞~
2021-11-5 16:52
_Kernel
为你点赞~
2021-11-5 16:45
不懂就不懂
为你点赞~
2021-11-5 16:34
0x太上
为你点赞~
2021-11-5 16:33
丶基
为你点赞~
2021-11-5 16:32
Jev0n
为你点赞~
2021-11-5 16:32
最新回复 (11)
雪    币: 1552
活跃值: (2627)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
好棒哦
2021-11-5 16:33
0
雪    币: 43
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
牛逼666我滴宝贝
2021-11-5 16:33
0
雪    币: 889
活跃值: (4117)
能力值: ( LV6,RANK:98 )
在线值:
发帖
回帖
粉丝
4
2021-11-5 16:39
1
雪    币: 402
活跃值: (4232)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
2021-11-5 16:40
0
雪    币: 1281
活跃值: (1248)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
6
2021-11-5 16:41
0
雪    币: 17
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
牛逼666我滴宝贝
2021-11-5 16:45
0
雪    币: 2134
活跃值: (3911)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
8
2021-11-5 16:46
0
雪    币: 2408
活跃值: (2838)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
看起来就是sfilter
2021-11-8 11:23
0
雪    币: 402
活跃值: (4232)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
dearfuture 看起来就是sfilter
比Sfilter更底层
2021-11-8 19:40
0
雪    币: 27
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
2021-12-8 16:19
0
雪    币: 199
活跃值: (607)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
2022-6-28 17:25
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册