首页
社区
课程
招聘
[分享]关于过滤
发表于: 2011-4-28 14:56 7004

[分享]关于过滤

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

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//