Filter-Hook Driver入门 -1

 Filter-Hook Driver入门(1)     ☆ Filter-Hook Driver

    ☆ PacketFilterExtensionPtr
    ☆ 设置/清除回调函数
        1) 调用IoGetDeviceObjectPointer()获取IpFilterDriver相应的设备对象
        2) 调用IoBuildDeviceIoControlRequest()构造IRP
        3) 调用IoCallDriver()向IpFilterDriver提交IRP
    ☆ 一个完整的Filter-Hook Driver框架(丢弃所有ICMP报文以及接收到的RST报文)
        1) ipflthookdrv.c
        2) dirs
        3) sources
        4) makefile
        5) installdriver.c
        6) ipflthookdrvtest.c
        7) 验证效果
    ☆ 参考资源
 
--------------------------------------------------------------------------
 
☆ Filter-Hook Driver
 
从Windows 2000开始IpFilterDriver是系统自带的一个驱动,顾名思义,就是IP过滤
驱动,对应ipfltdrv.sys文件。缺省情况下,这个驱动并未加载,但可以手工加载。
 
> sc queryex IpFilterDriver
SERVICE_NAME: IpFilterDriver
        TYPE               : 1  KERNEL_DRIVER
        STATE              : 1  STOPPED
                                (NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 0
        FLAGS              :
> enumservice.exe findstr /I ipfilter
设备驱动程序            停止     IpFilterDriver                 IP Traffic Filter Driver
> net start IpFilterDriver
The IP Traffic Filter Driver service was started sUCcessfully.
> enumservice.exe findstr /I ipfilter
设备驱动程序            运行     IpFilterDriver                 IP Traffic Filter Driver
> net stop IpFilterDriver
The IP Traffic Filter Driver service was stopped successfully.
 
Filter-Hook Driver是一种KMD,与IpFilterDriver相配合。显然这只能用于TCP/IP
协议,而对IPX/SPX、NetBEUI等其它协议无能为力。
 
最多只能安装一个Filter-Hook Driver。仅当filter-hook callback function为空
时,Filter-Hook Driver才能向IpFilterDriver注册自己所提供的回调函数,后者调
用filter-hook callback function以决定如何处理接收到的或者即将发送的IP报文。
注册回调函数结束之后,IpFilterDriver将Filter-Hook Driver相应的文件对象与回
调函数关联起来,以此确保只有一个Filter-Hook Driver可用。
 
从Windows XP开始,微软不推荐采用Filter-Hook Driver实现防火墙。从网络层次结
构上看,Filter-Hook Driver太高了。此外,Filter-Hook Driver还将干挠到ICS或
其它个人防火墙。ICS即Internet Connection Sharing,可以简单理解成XP/2003自
带的个人防火墙,当然事实上并非这么简单,ICS可以实现端口转发、NAT等类似功能。
如果你愿意,可以试着利用ICS将一台XP/2003配成NAT网关,我未实际测试,tk做过
一些实验。对于XP/2003,推荐采用NDIS Intermediate Driver实现防火墙。尽管如
此,我还是学习一下Filter-Hook Driver,因为它实现起来相对简单些。
 
用户态有一套Packet Filtering API,直接与IpFilterDriver打交道,做了适度优化,
可以根据srcIp、dstIp、srcPort、dstPort等等进行过滤,但与Filter-Hook Driver
无关!如果只关注IP地址和端口,可以考虑该套API,但试图过滤ICMP报文时就应考
虑Filter-Hook Driver。
 
☆ PacketFilterExtensionPtr
 
前面提到的回调函数的原型如下:
 
typedef  PF_FORWARD_ACTION ( *PacketFilterExtensionPtr )
(
    IN  unsigned char  *PacketHeader,
    IN  unsigned char  *Packet,
    IN  unsigned int    PacketLength,
    IN  unsigned int    RecvInterfaceIndex,
    IN  unsigned int    SendInterfaceIndex,
    IN  IPAddr          RecvLinkNextHop,
    IN  IPAddr          SendLinkNextHop
);
 
由于是回调函数,函数名是什么都无所谓,DDK文档建议起一个有意义的名字。该函
数有三种返回值:
 
PF_FORWARD
 
    直接交给IP协议栈处理。如果IP报文是发给本机的,延IP协议栈向上传输。如果
    IP报文是发给另一台主机的,并且本机使能了"IP转发(路由功能)",则根据路由
    表进行相应转发。
 
PF_DROP
 
    IP协议栈将丢弃该IP报文。
 
PF_PASS
 
    如果用户态Packet Filtering API定义了过滤规则,在此得到机会进行过滤。如
    果Filter-Hook Driver觉得应该给用户态Packet Filtering API一个机会,必须
    返回PF_PASS,此时由IpFilterDriver亲自过滤。返回PF_FORWARD意味着Packet
    Filtering API所定义的过滤规则失效,嘿嘿。
 
☆ 设置/清除回调函数
 
1) 调用IoGetDeviceObjectPointer()获取IpFilterDriver相应的设备对象
 
NTSTATUS IoGetDeviceObjectPointer
(
    IN  PUNICODE_STRING     ObjectName,
    IN  Access_MASK         DesiredAccess,
    OUT PFILE_OBJECT       *FileObject,
    OUT PDEVICE_OBJECT     *DeviceObject
);
 
ObjectName
 
    要对应DD_IPFLTRDRVR_DEVICE_NAME,这是pfhook.h中定义的宏,即
    L"\\Device\\IPFILTERDRIVER"。注意ObjectName的类型,需要调用
    RtlInitUnicodeString()。
 
DesiredAccess
 
    DDK文档中指出应指定"SYNCHRONIZE GENERIC_READ GENERIC_WRITE"。如果
    图省事,可以指定STANDARD_RIGHTS_ALL。
 
    参看Platform SDK DOC中ACCESS_MASK Reference。
 
FileObject
 
    卸载Filter-Hook Driver时,应调用ObDereferenceObject()减小这个文件对象
    的引用计数,此时将间接减小相应设备对象的引用计数,否则IpFilterDriver无
    法正确卸载。
 
    VOID ObDereferenceObject
    (
        IN  PVOID   Object
    );
 
DeviceObject
 
    后面将用到这个返回数据
 
2) 调用IoBuildDeviceIoControlRequest()构造IRP
 
PIRP IoBuildDeviceIoControlRequest
(
    IN  ULONG               IoControlCode,
    IN  PDEVICE_OBJECT      DeviceObject,
    IN  PVOID               InputBuffer     OPTIONAL,
    IN  ULONG               InputBufferLength,
    OUT PVOID               OutputBuffer    OPTIONAL,
    IN  ULONG               OutputBufferLength,
    IN  BOOLEAN             InternalDeviceIoControl,
    IN  PKEVENT             Event,
    OUT PIO_STATUS_BLOCK    IoStatusBlock
);
 
IoControlCode
 
    必须指定IOCTL_PF_SET_EXTENSION_POINTER
 
DeviceObject
 
    IpFilterDriver相应的设备对象
 
InputBuffer
 
    应该强制类型转换成PPF_SET_EXTENSION_HOOK_INFO,其ExtensionPointer成员
    等于回调函数地址。如果ExtensionPointer成员为NULL,意味着清除操作。
 
    typedef struct _PF_SET_EXTENSION_HOOK_INFO
    {
        PacketFilterExtensionPtr    ExtensionPointer;
    } PF_SET_EXTENSION_HOOK_INFO, *PPF_SET_EXTENSION_HOOK_INFO;
 
    卸载Filter-Hook Driver时,必须清除回调函数。
 
InputBufferLength
 
    sizeof( PF_SET_EXTENSION_HOOK_INFO )
 
OutputBuffer
 
    NULL
 
OutputBufferLength
 
    0
 
InternalDeviceIoControl
 
    必须指定成FALSE,使得IpFilterDriver处理IRP_MJ_DEVICE_CONTROL的Dispatch
    例程被调用。
 
Event
 
    NULL
 
IoStatusBlock
 
    应该指定一个有效值
 
3) 调用IoCallDriver()向IpFilterDriver提交IRP
 
NTSTATUS IoCallDriver
(
    IN      PDEVICE_OBJECT  DeviceObject,
    IN OUT  PIRP            Irp
);
 
DeviceObject
 
    IpFilterDriver相应的设备对象
 
Irp
 
    第2步构造的IRP
 
☆ 一个完整的Filter-Hook Driver框架(丢弃所有ICMP报文以及接收到的RST报文)
 
1) ipflthookdrv.c
 
本例可以丢弃所有ICMP报文以及接收到的RST报文。一般丢弃所有ICMP报文并不会造
成大的问题。显然,ping、tracert这类依赖ICMP报文的工具将无法正常使用,别人
也不能ping你,呵。根据th_flags丢弃所有发送到本机的RST报文,但允许本机发送
RST报文给别人。至于TCP/IP协议相关的更复杂的演示就不搞了,毕竟不是正经写防
火墙。
 
--------------------------------------------------------------------------
/*
* For x86/EWindows XP SP1 & VC 7 & Windows DDK 2600.1106
* build -cZ -x86
*/
 
/************************************************************************
*                                                                      *
*                               Head File                              *
*                                                                      *
************************************************************************/
 
#include <ntddk.h>
/*
* typedef ULONG   IPAddr, IPMask;
*/
#include <ntddndis.h>
#include <pfhook.h>
/*
* 用到了CTL_CODE宏
*/
#include <devioctl.h>

你可能感兴趣的:(入门,职场,driver,休闲)