-
-
[分享]关于过滤
-
发表于: 2011-4-28 14:56 7004
-
意淫一下
过滤一般都是两个步骤
一个是信息的拦截
一个是信息的解析和反馈
拦截是必须的
而解析是核心
说说常见过滤是怎样拦截的
键盘
一般键盘消息是在WndProc得到的。
它的来源
一个是GetMessage->DispatchMessage ->WndProc得到的,这个是正常的途径
一个是设置了键盘钩子,直接在内核KeUserModeCallback回调来的。
而内核里的消息的产生是由子系统发送的:
简单的堆栈:
kbdclass!KeyboardClassRead
nt!IopfCallDriver+0x31
nt!IopSynchronousServiceTail+0x60
nt!NtReadFile+0x580
nt!KiFastCallEntry+0xf8
nt!ZwReadFile+0x11
win32k!StartDeviceRead+0x154
win32k!InputApc+0x66
nt!KiDeliverApc+0x124
nt!KiSwapThread+0x64
nt!KeWaitForMultipleObjects+0x284
win32k!RawInputThread+0x4f3
win32k!xxxCreateSystemThreads+0x60
win32k创建线程用ZwReadFile循环获取键盘信息,然后转换成消息挂入线程的消息队列进行消息分发。
而ZwReadFile是通过发送IRP从键盘类驱动kbdclass中获取信息的。
kbdclass 是一个类驱动,在端口驱动上层,它向端口驱动(i8042prt)注册了服务回调KeyboardClassServiceCallback。
当有READ的IRP到时,把IRP挂入IRP队列串行化,然后返回PENDING。
键盘消息是由端口驱动获得的。
一般的端口驱动都是这样的:
注册(关联)一个中断服务IoConnectInterrupt
然后在中断服务里挂一个延迟调用KeInsertQueueDpc
在DPC例程里调用上一层(一般是类驱动)注册的服务回调函数,由服务回调函数处理IRP队列。
*****************中断*********************
i8042prt!I8042KeyboardInterruptService
nt!KiInterruptDispatch+0x3d
*****************回调********************
kbdclass!KeyboardClassServiceCallback+0x77
i8042prt!I8042KeyboardIsrDpc+0xf0
nt!KiRetireDpcList+0x46
而中断的产生和IRQ与IDT的关系。。。。。看Inter手册
IoConnectInterrup和IRQL是微软的硬件抽象,提供了硬件无关的中断接口
常见几种过滤点
低级键盘钩子
过滤KiUserCallbackDispatcher
键盘设备Attach
键盘驱动hook
IDT
键盘是最简单的
下面看看文件系统的
文件系统的层次大约是这样的
-------------文件系统------------------------------------------------------------------
minifilter 用户的微过滤驱动
filter ftlmgr.sys--文件过滤驱动
fsd 文件系统 driver: \FileSystem\Ntfs,设备无名
--------------卷管理------------------------------------------------------------------
volfilter volsnap.sys --卷过滤驱动 设备无名
voldriver ftdisk.sys --卷设备驱动 \Device\HarddiskVolumX
-------------磁盘管理------------------------------------------------------------------
diskfilter 其他磁盘过滤驱动
partition partmgr.sys分区管理 设备无名,堆叠在disk上层
classmgr classpnp.sys本身无设备,提供函数给disk.sys,帮类驱动创建设备
class disk.sys \Device\HarddiskX\DRX
port scsiport/pciide,pdideex本身无设备 提供给微端口函数,帮微端口驱动创建设备
miniport 由硬件厂商开发,硬件操作 \Device\Scsi\ScsiPortx
\Device\Ide\IdePortX
-----------------------------------------------------------------------------------------
下面看看堆栈
虽然形式看起来是堆叠在一起的,可是为了更好的扩展,他们的设备实际上是不完全堆叠的
---------------------磁盘---------------------------------
atapi!IdePortDispatch
nt!IopfCallDriver+0x31
CLASSPNP!SubmitTransferPacket+0x82 |
CLASSPNP!ServiceTransferRequest+0xe4 |-->这里是disk的设备,不过是由classpnp分发的
CLASSPNP!ClassReadWrite+0xff |
nt!IopfCallDriver+0x31
PartMgr!PmReadWrite+0x93
nt!IopfCallDriver+0x31
diskperf!DiskPerfReadWrite+0x1b3
典型的端口-类-类过滤,这个跟键盘是类似的
PartMgr读取磁盘分区表通知卷去创建
分区由卷管理
一个卷管理一个或多个分区
-------------------卷--------------------------------
nt!IopfCallDriver+0x31
ftdisk!FtDiskReadWrite+0x194
nt!IopfCallDriver+0x31
VolSnap!VolSnapWrite+0xbb
关于卷的创建
ftdisk注册PNP接口IoRegisterDeviceInterface
partmgr,mountmgr注册回调IoRegisterPlugPlayNotification
nt!IoCreateSymbolicLink -->\GLOBAL??\C:
MountMgr!GlobalCreateSymbolicLink+0x25
MountMgr!CreateNewDriveLetterName+0xfe
MountMgr!MountMgrMountedDeviceArrival+0x86a
MountMgr!MountMgrMountedDeviceNotification+0x4b Mountmgr设置设备变化回调,又新卷生成时便
nt!PiNotifyDriverCallback+0x6f 为其创建符合链接
nt!IopNotifyDeviceClassChange+0xb5
nt!PiWalkDeviceList+0xe1
------------------------------------------------------------------------
nt!IoCreateDevice -->\Device\HarddiskVolumX
ftdisk!FtpCreateNewDevice+0x52
ftdisk!FtpPartitionArrivedHelper+0x45f
ftdisk!FtpPartitionArrived+0x26
ftdisk!FtDiskInternalDeviceControl+0x84
nt!IopfCallDriver+0x31
PartMgr!PmGivePartition+0x91
PartMgr!PmQueryDeviceRelations+0x1de -->PartMgr根据分区表通知ftdisk建立卷设备
PartMgr!PmPnp+0x18b
nt!IopfCallDriver+0x31
diskperf!DiskPerfSendToNextDriver+0x3c
diskperf!DiskPerfDispatchPnp+0x25c
nt!IopfCallDriver+0x31
nt!IopSynchronousCall+0xb7
nt!IopQueryDeviceRelations+0x45
nt!PipEnumerateDevice+0x23
nt!PipProcessDevNodeTree+0x21b -->
nt!PipDeviceActionWorker+0xa3
nt!PipRequestDeviceAction+0x107
nt!IopInitializeBootDrivers+0x376 -->加载PNP驱动
卷虽然建立了,可是它只是一个存储块,没有文件的概念的
卷内容的解析是由文件系统完成的
文件系统和卷不是堆叠的关系,而是挂载(Mount)和被挂载的关系
文件系统与卷的关系:
文件系统在建立时都会向操作系统注册自己IoRegisterFileSystem,把自己挂入文件系统队列
访问文件时,会经过IopParseFile->IopParseDevice,然后检查卷是否挂载了文件系统
IopCheckVpbMounted,不是就IopMountVolume向文件系统队列每个FSD发送MOUNT_VOLUME请求,完成文件系统与卷的关联
-----------------文件系统-------------------------------
nt!IopfCallDriver+0x31
Ntfs!NtfsSingleAsync+0x6d
Ntfs!NtfsNonCachedIo+0x2f8
Ntfs!NtfsCommonWrite+0x1824 ->IRP发送到文件系统,再由文件系统发送给关联的卷
Ntfs!NtfsFsdWrite+0xf3 形式上形成了堆叠。
而文件系统的格式。。。蛋都碎了。。
文件读取还跟缓存有关,缓存又扯上内存管理,映射,内存管理又和保护模式有不能不说的关系。。。
------------------------------------------------------
文件系统之上就是FSD过滤驱动了
大家都知道的sfilter
和sfilter的包装版minifilter
哎,其实用什么过滤都是浮云,重要的是过滤时获取的信息怎么解析,怎么传递反馈。
网络
网络差不多就是一个子系统了,复杂的从不是数据的拦截,而是数据的解析
拦截主要是三个接口
SPI
TDI
NDIS
过滤一般都是两个步骤
一个是信息的拦截
一个是信息的解析和反馈
拦截是必须的
而解析是核心
说说常见过滤是怎样拦截的
键盘
一般键盘消息是在WndProc得到的。
它的来源
一个是GetMessage->DispatchMessage ->WndProc得到的,这个是正常的途径
一个是设置了键盘钩子,直接在内核KeUserModeCallback回调来的。
而内核里的消息的产生是由子系统发送的:
简单的堆栈:
kbdclass!KeyboardClassRead
nt!IopfCallDriver+0x31
nt!IopSynchronousServiceTail+0x60
nt!NtReadFile+0x580
nt!KiFastCallEntry+0xf8
nt!ZwReadFile+0x11
win32k!StartDeviceRead+0x154
win32k!InputApc+0x66
nt!KiDeliverApc+0x124
nt!KiSwapThread+0x64
nt!KeWaitForMultipleObjects+0x284
win32k!RawInputThread+0x4f3
win32k!xxxCreateSystemThreads+0x60
win32k创建线程用ZwReadFile循环获取键盘信息,然后转换成消息挂入线程的消息队列进行消息分发。
而ZwReadFile是通过发送IRP从键盘类驱动kbdclass中获取信息的。
kbdclass 是一个类驱动,在端口驱动上层,它向端口驱动(i8042prt)注册了服务回调KeyboardClassServiceCallback。
当有READ的IRP到时,把IRP挂入IRP队列串行化,然后返回PENDING。
键盘消息是由端口驱动获得的。
一般的端口驱动都是这样的:
注册(关联)一个中断服务IoConnectInterrupt
然后在中断服务里挂一个延迟调用KeInsertQueueDpc
在DPC例程里调用上一层(一般是类驱动)注册的服务回调函数,由服务回调函数处理IRP队列。
*****************中断*********************
i8042prt!I8042KeyboardInterruptService
nt!KiInterruptDispatch+0x3d
*****************回调********************
kbdclass!KeyboardClassServiceCallback+0x77
i8042prt!I8042KeyboardIsrDpc+0xf0
nt!KiRetireDpcList+0x46
而中断的产生和IRQ与IDT的关系。。。。。看Inter手册
IoConnectInterrup和IRQL是微软的硬件抽象,提供了硬件无关的中断接口
常见几种过滤点
低级键盘钩子
过滤KiUserCallbackDispatcher
键盘设备Attach
键盘驱动hook
IDT
键盘是最简单的
下面看看文件系统的
文件系统的层次大约是这样的
-------------文件系统------------------------------------------------------------------
minifilter 用户的微过滤驱动
filter ftlmgr.sys--文件过滤驱动
fsd 文件系统 driver: \FileSystem\Ntfs,设备无名
--------------卷管理------------------------------------------------------------------
volfilter volsnap.sys --卷过滤驱动 设备无名
voldriver ftdisk.sys --卷设备驱动 \Device\HarddiskVolumX
-------------磁盘管理------------------------------------------------------------------
diskfilter 其他磁盘过滤驱动
partition partmgr.sys分区管理 设备无名,堆叠在disk上层
classmgr classpnp.sys本身无设备,提供函数给disk.sys,帮类驱动创建设备
class disk.sys \Device\HarddiskX\DRX
port scsiport/pciide,pdideex本身无设备 提供给微端口函数,帮微端口驱动创建设备
miniport 由硬件厂商开发,硬件操作 \Device\Scsi\ScsiPortx
\Device\Ide\IdePortX
-----------------------------------------------------------------------------------------
下面看看堆栈
虽然形式看起来是堆叠在一起的,可是为了更好的扩展,他们的设备实际上是不完全堆叠的
---------------------磁盘---------------------------------
atapi!IdePortDispatch
nt!IopfCallDriver+0x31
CLASSPNP!SubmitTransferPacket+0x82 |
CLASSPNP!ServiceTransferRequest+0xe4 |-->这里是disk的设备,不过是由classpnp分发的
CLASSPNP!ClassReadWrite+0xff |
nt!IopfCallDriver+0x31
PartMgr!PmReadWrite+0x93
nt!IopfCallDriver+0x31
diskperf!DiskPerfReadWrite+0x1b3
典型的端口-类-类过滤,这个跟键盘是类似的
PartMgr读取磁盘分区表通知卷去创建
分区由卷管理
一个卷管理一个或多个分区
-------------------卷--------------------------------
nt!IopfCallDriver+0x31
ftdisk!FtDiskReadWrite+0x194
nt!IopfCallDriver+0x31
VolSnap!VolSnapWrite+0xbb
关于卷的创建
ftdisk注册PNP接口IoRegisterDeviceInterface
partmgr,mountmgr注册回调IoRegisterPlugPlayNotification
nt!IoCreateSymbolicLink -->\GLOBAL??\C:
MountMgr!GlobalCreateSymbolicLink+0x25
MountMgr!CreateNewDriveLetterName+0xfe
MountMgr!MountMgrMountedDeviceArrival+0x86a
MountMgr!MountMgrMountedDeviceNotification+0x4b Mountmgr设置设备变化回调,又新卷生成时便
nt!PiNotifyDriverCallback+0x6f 为其创建符合链接
nt!IopNotifyDeviceClassChange+0xb5
nt!PiWalkDeviceList+0xe1
------------------------------------------------------------------------
nt!IoCreateDevice -->\Device\HarddiskVolumX
ftdisk!FtpCreateNewDevice+0x52
ftdisk!FtpPartitionArrivedHelper+0x45f
ftdisk!FtpPartitionArrived+0x26
ftdisk!FtDiskInternalDeviceControl+0x84
nt!IopfCallDriver+0x31
PartMgr!PmGivePartition+0x91
PartMgr!PmQueryDeviceRelations+0x1de -->PartMgr根据分区表通知ftdisk建立卷设备
PartMgr!PmPnp+0x18b
nt!IopfCallDriver+0x31
diskperf!DiskPerfSendToNextDriver+0x3c
diskperf!DiskPerfDispatchPnp+0x25c
nt!IopfCallDriver+0x31
nt!IopSynchronousCall+0xb7
nt!IopQueryDeviceRelations+0x45
nt!PipEnumerateDevice+0x23
nt!PipProcessDevNodeTree+0x21b -->
nt!PipDeviceActionWorker+0xa3
nt!PipRequestDeviceAction+0x107
nt!IopInitializeBootDrivers+0x376 -->加载PNP驱动
卷虽然建立了,可是它只是一个存储块,没有文件的概念的
卷内容的解析是由文件系统完成的
文件系统和卷不是堆叠的关系,而是挂载(Mount)和被挂载的关系
文件系统与卷的关系:
文件系统在建立时都会向操作系统注册自己IoRegisterFileSystem,把自己挂入文件系统队列
访问文件时,会经过IopParseFile->IopParseDevice,然后检查卷是否挂载了文件系统
IopCheckVpbMounted,不是就IopMountVolume向文件系统队列每个FSD发送MOUNT_VOLUME请求,完成文件系统与卷的关联
-----------------文件系统-------------------------------
nt!IopfCallDriver+0x31
Ntfs!NtfsSingleAsync+0x6d
Ntfs!NtfsNonCachedIo+0x2f8
Ntfs!NtfsCommonWrite+0x1824 ->IRP发送到文件系统,再由文件系统发送给关联的卷
Ntfs!NtfsFsdWrite+0xf3 形式上形成了堆叠。
而文件系统的格式。。。蛋都碎了。。
文件读取还跟缓存有关,缓存又扯上内存管理,映射,内存管理又和保护模式有不能不说的关系。。。
------------------------------------------------------
文件系统之上就是FSD过滤驱动了
大家都知道的sfilter
和sfilter的包装版minifilter
哎,其实用什么过滤都是浮云,重要的是过滤时获取的信息怎么解析,怎么传递反馈。
网络
网络差不多就是一个子系统了,复杂的从不是数据的拦截,而是数据的解析
拦截主要是三个接口
SPI
TDI
NDIS
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
看原图
赞赏
雪币:
留言: