ipfltdrv

/
02// DrvFltIp.h文件
03  
04#ifndef __DRVFLTIP_H__
05#define __DRVFLTIP_H__
06  
07// 自定义设备类型,在创建设备对象时使用
08// 注意,自定义值的范围是32768-65535
09#define FILE_DEVICE_DRVFLTIP  0x00654322
10  
11// 自定义的IO控制代码,用于区分不同的设备控制请求
12// 注意,自定义值的范围是2048-4095
13#define DRVFLTIP_IOCTL_INDEX  0x830
14  
15//
16// 定义各种设备控制代码。分别是开始过滤、停止过滤、添加过滤规则、清除过滤规则
17// 
18#define START_IP_HOOK   CTL_CODE(FILE_DEVICE_DRVFLTIP, \
19                DRVFLTIP_IOCTL_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS)
20#define STOP_IP_HOOK    CTL_CODE(FILE_DEVICE_DRVFLTIP, \
21                DRVFLTIP_IOCTL_INDEX+1, METHOD_BUFFERED, FILE_ANY_ACCESS)
22#define ADD_FILTER  CTL_CODE(FILE_DEVICE_DRVFLTIP, \
23                DRVFLTIP_IOCTL_INDEX+2, METHOD_BUFFERED, FILE_WRITE_ACCESS)
24#define CLEAR_FILTER    CTL_CODE(FILE_DEVICE_DRVFLTIP, \
25                DRVFLTIP_IOCTL_INDEX+3, METHOD_BUFFERED, FILE_ANY_ACCESS)
26  
27// 定义过滤规则的结构
28struct CIPFilter
29{
30    USHORT protocol;        // 使用的协议
31  
32    ULONG sourceIP;         // 源IP地址
33    ULONG destinationIP;        // 目标IP地址
34  
35    ULONG sourceMask;       // 源地址屏蔽码
36    ULONG destinationMask;      // 目的地址屏蔽码
37  
38    USHORT sourcePort;      // 源端口号
39    USHORT destinationPort;     // 目的端口号
40      
41    BOOLEAN bDrop;          // 是否丢弃此封包
42};
43  
44#endif // __DRVFLTIP_H__

[文件] internal.h ~ 1KB    下载(53)

01///
02// internal.h文件
03  
04  
05// 过滤列表
06struct CFilterList
07{
08    CIPFilter ipf;      // 过滤规则
09    CFilterList* pNext; // 指向下一个CFilterList结构
10};
11  
12typedef struct IPHeader 
13{
14    UCHAR     iphVerLen;      // 版本号和头长度(各占4位)
15    UCHAR     ipTOS;          // 服务类型 
16    USHORT    ipLength;       // 封包总长度,即整个IP报的长度
17    USHORT    ipID;       // 封包标识,惟一标识发送的每一个数据报
18    USHORT    ipFlags;        // 标志
19    UCHAR     ipTTL;          // 生存时间,就是TTL
20    UCHAR     ipProtocol;     // 协议,可能是TCP、UDP、ICMP等
21    USHORT    ipChecksum;     // 校验和
22    ULONG     ipSource;       // 源IP地址
23    ULONG     ipDestination;  // 目标IP地址
24} IPPacket; 
25  
26  
27typedef struct _TCPHeader
28{
29    USHORT          sourcePort;     // 源端口号
30    USHORT          destinationPort;    // 目的端口号
31    ULONG           sequenceNumber;     // 序号
32    ULONG           acknowledgeNumber;  // 确认序号
33    UCHAR           dataoffset;     // 数据指针
34    UCHAR           flags;          // 标志
35    USHORT          windows;        // 窗口大小
36    USHORT          checksum;       // 校验和
37    USHORT          urgentPointer;      // 紧急指针
38} TCPHeader;
39  
40typedef struct _UDPHeader
41{
42    USHORT          sourcePort;     // 源端口号     
43    USHORT          destinationPort;    // 目的端口号        
44    USHORT          len;            // 封包长度
45    USHORT          checksum;       // 校验和
46} UDPHeader;

[文件] DrvFltIp.cpp ~ 9KB    下载(48)

001// DrvFltIp.cpp文件
002  
003  
004extern "C"
005{
006    #include <ntddk.h>
007    #include <ntddndis.h>
008    #include <pfhook.h>
009}
010  
011#include "DrvFltIp.h"
012#include "internal.h"
013  
014// 自定义函数的声明
015NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
016void DriverUnload(PDRIVER_OBJECT pDriverObj);
017NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
018NTSTATUS AddFilterToList(CIPFilter* pFilter);
019void ClearFilterList();
020NTSTATUS SetFilterFunction(PacketFilterExtensionPtr filterFun);
021PF_FORWARD_ACTION FilterPackets(unsigned char*, unsigned char*, unsigned int, unsigned int, unsigned int, IPAddr, IPAddr);
022  
023// 过滤列表首地址
024struct CFilterList* g_pHeader = NULL;
025  
026  
027// 驱动内部名称和符号连接名称
028#define DEVICE_NAME L"\\Device\\devDrvFltIp"
029#define LINK_NAME L"\\??\\DrvFltIp"
030  
031  
032NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
033{
034    NTSTATUS status = STATUS_SUCCESS;
035  
036    // 初始化各个派遣例程
037    pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
038    pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
039    pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
040    pDriverObj->DriverUnload = DriverUnload;
041  
042        // 创建、初始化设备对象
043    // 设备名称
044    UNICODE_STRING ustrDevName;
045    RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
046    // 创建设备对象
047    PDEVICE_OBJECT pDevObj;
048    status = IoCreateDevice(pDriverObj, 
049                0,
050                &ustrDevName, 
051                FILE_DEVICE_DRVFLTIP,
052                0,
053                FALSE,
054                &pDevObj);
055    if(!NT_SUCCESS(status))
056    {
057        return status;
058    }
059  
060        // 创建符号连接名称
061    // 符号连接名称
062    UNICODE_STRING ustrLinkName;
063    RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
064    // 创建关联
065    status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
066    if(!NT_SUCCESS(status))
067    {
068        IoDeleteDevice(pDevObj);
069        return status;
070    }
071      
072    return STATUS_SUCCESS;
073}
074  
075  
076void DriverUnload(PDRIVER_OBJECT pDriverObj)
077{   
078    // 卸载过滤函数
079    SetFilterFunction(NULL);
080    // 释放所有资源
081    ClearFilterList();
082  
083    // 删除符号连接名称
084    UNICODE_STRING strLink;
085    RtlInitUnicodeString(&strLink, LINK_NAME);
086    IoDeleteSymbolicLink(&strLink);
087  
088    // 删除设备对象
089    IoDeleteDevice(pDriverObj->DeviceObject);
090}
091  
092// 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
093NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
094{
095    pIrp->IoStatus.Status = STATUS_SUCCESS;
096//  pIrp->IoStatus.Information = 0;
097    // 完成此请求
098    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
099  
100    return STATUS_SUCCESS;
101}
102  
103  
104// I/O控制派遣例程
105NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
106{
107    NTSTATUS status = STATUS_SUCCESS;
108  
109    // 取得此IRP(pIrp)的I/O堆栈指针
110    PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
111  
112    // 取得I/O控制代码
113    ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
114    // 取得I/O缓冲区指针和它的长度
115    PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
116    ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
117      
118    // 响应用户的命令
119    switch(uIoControlCode)
120    {
121    case START_IP_HOOK: // 开始过滤
122        status = SetFilterFunction(FilterPackets);
123        break;
124  
125    case STOP_IP_HOOK:  // 停止过滤
126        status = SetFilterFunction(NULL);
127        break;
128  
129    case ADD_FILTER:    // 添加一个过滤规则
130        if(uInSize == sizeof(CIPFilter))
131            status = AddFilterToList((CIPFilter*)pIoBuffer);
132        else 
133            status = STATUS_INVALID_DEVICE_REQUEST;
134        break;
135  
136    case CLEAR_FILTER:  // 释放过滤规则列表
137        ClearFilterList();
138        break;
139  
140    default:
141        status = STATUS_INVALID_DEVICE_REQUEST;
142        break;
143    }
144      
145    // 完成请求
146    pIrp->IoStatus.Status = status;
147    pIrp->IoStatus.Information = 0;
148    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
149  
150    return status;
151}
152  
153  
154  
155///
156//过滤列表
157  
158// 向过滤列表中添加一个过滤规则
159NTSTATUS AddFilterToList(CIPFilter* pFilter)
160{
161    // 为新的过滤规则申请内存空间
162    CFilterList* pNew = (CFilterList*)ExAllocatePool(NonPagedPool, sizeof(CFilterList));
163    if(pNew == NULL)
164        return STATUS_INSUFFICIENT_RESOURCES;
165  
166    // 填充这块内存
167    RtlCopyMemory(&pNew->ipf, pFilter, sizeof(CIPFilter));
168      
169    // 连接到过滤列表中
170    pNew->pNext = g_pHeader;
171    g_pHeader = pNew;
172  
173    return STATUS_SUCCESS;
174}
175  
176// 清除过滤列表
177void ClearFilterList()
178{
179    CFilterList* pNext;
180    // 释放过滤列表占用的所有内存
181    while(g_pHeader != NULL)
182    {
183        pNext = g_pHeader->pNext;
184        // 释放内存
185        ExFreePool(g_pHeader);
186        g_pHeader = pNext;
187    }
188}
189  
190
191//过滤函数
192  
193// 过滤钩子回调函数
194PF_FORWARD_ACTION FilterPackets(
195        unsigned char   *PacketHeader,
196        unsigned char   *Packet,
197        unsigned int    PacketLength,
198        unsigned int    RecvInterfaceIndex,
199        unsigned int    SendInterfaceIndex,
200        IPAddr          RecvLinkNextHop,
201        IPAddr          SendLinkNextHop)
202{
203    // 提取IP头
204    IPHeader* pIPHdr = (IPHeader*)PacketHeader;
205  
206    if(pIPHdr->ipProtocol == 6)  // 是TCP协议?
207    {
208        // 提取TCP头
209        TCPHeader* pTCPHdr = (TCPHeader*)Packet;
210        // 我们接受所有已经建立连接的TCP封包
211        if(!(pTCPHdr->flags & 0x02))
212        {
213            return PF_FORWARD;
214        }
215    }
216  
217    // 与过滤规则相比较,决定采取的行动
218    CFilterList* pList = g_pHeader;
219    while(pList != NULL)
220    {
221        // 比较协议
222        if(pList->ipf.protocol == 0 || pList->ipf.protocol == pIPHdr->ipProtocol)
223        {
224            // 查看源IP地址
225            if(pList->ipf.sourceIP != 0 && 
226                (pList->ipf.sourceIP & pList->ipf.sourceMask) != pIPHdr->ipSource)
227            {
228                pList = pList->pNext;
229                continue;
230            }
231  
232            // 查看目标IP地址
233            if(pList->ipf.destinationIP != 0 && 
234                (pList->ipf.destinationIP & pList->ipf.destinationMask) != pIPHdr->ipDestination)
235            {
236                pList = pList->pNext;
237                continue;
238            }
239  
240            // 如果是TCP封包,查看端口号
241            if(pIPHdr->ipProtocol == 6)
242            {
243                TCPHeader* pTCPHdr = (TCPHeader*)Packet;
244                if(pList->ipf.sourcePort == 0 || pList->ipf.sourcePort == pTCPHdr->sourcePort)
245                {
246                    if(pList->ipf.destinationPort == 0 
247                        || pList->ipf.destinationPort == pTCPHdr->destinationPort)
248                    {
249                        // 现在决定如何处理这个封包
250                        if(pList->ipf.bDrop)
251                            return PF_DROP;
252                        else
253                            return PF_FORWARD;
254                    }
255                }
256            }
257  
258            // 如果是UDP封包,查看端口号
259            else if(pIPHdr->ipProtocol == 17)
260            {
261                UDPHeader* pUDPHdr = (UDPHeader*)Packet;
262                if(pList->ipf.sourcePort == 0 || pList->ipf.sourcePort == pUDPHdr->sourcePort)
263                {
264                    if(pList->ipf.destinationPort == 0 
265                        || pList->ipf.destinationPort == pUDPHdr->destinationPort)
266                    {
267                        // 现在决定如何处理这个封包
268                        if(pList->ipf.bDrop)
269                            return PF_DROP;
270                        else
271                            return PF_FORWARD;
272                    }
273                }
274            }
275            else 
276            {
277                // 对于其它封包,我们直接处理
278                if(pList->ipf.bDrop)
279                        return PF_DROP;
280                    else
281                        return PF_FORWARD;
282            }
283        }
284  
285        // 比较下一个规则
286        pList = pList->pNext;
287    }
288  
289    // 我们接受所有没有注册的封包
290    return PF_FORWARD;
291}
292  
293// 注册钩子回调函数
294NTSTATUS SetFilterFunction(PacketFilterExtensionPtr filterFun)
295{   
296    NTSTATUS status = STATUS_SUCCESS;
297  
298        // 取得IP过滤驱动设备对象。下面代码执行后,pDeviceObj变量将指向IP过滤驱动设备对象
299    PDEVICE_OBJECT pDeviceObj;
300    PFILE_OBJECT pFileObj;
301    // 初始化IP过滤驱动的名称
302    UNICODE_STRING ustrFilterDriver;
303    RtlInitUnicodeString(&ustrFilterDriver, L"\\Device\\IPFILTERDRIVER");
304    // 取得设备对象指针 
305    status = IoGetDeviceObjectPointer(&ustrFilterDriver, FILE_ALL_ACCESS, &pFileObj, &pDeviceObj);
306    if(!NT_SUCCESS(status))
307    {
308        return status;
309    }
310  
311        // 使用到IP过滤驱动中设备对象的指针创建一个IRP 
312    // 填充PF_SET_EXTENSION_HOOK_INFO结构
313    PF_SET_EXTENSION_HOOK_INFO filterData;
314    filterData.ExtensionPointer = filterFun;
315  
316    // 我们需要初始化一个事件对象。
317    // 构建IRP时需要使用这个事件内核对象,当IP过滤取得接受到此IRP,完成工作以后会将它置位
318    KEVENT event;
319    KeInitializeEvent(&event, NotificationEvent, FALSE);
320  
321    // 为设备控制请求申请和构建一个IRP
322    PIRP pIrp;
323    IO_STATUS_BLOCK ioStatus;
324    pIrp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER,  // io control code
325        pDeviceObj, 
326        (PVOID) &filterData,
327        sizeof(PF_SET_EXTENSION_HOOK_INFO),
328        NULL,
329        0,
330        FALSE,
331        &event,
332        &ioStatus);
333    if(pIrp == NULL)
334    {
335        // 如果不能申请空间,返回对应的错误代码
336        return STATUS_INSUFFICIENT_RESOURCES;
337    }
338      
339        // 请求安装钩子回调函数
340    // 发送此IRP到IP过滤驱动
341    status = IoCallDriver(pDeviceObj, pIrp);
=
342    // 等待IP过滤驱动的通知
343    if(status == STATUS_PENDING) 
344    {
345        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
346    }
347    status = ioStatus.Status;
348  
349    // 清除资源
350    if(pFileObj != NULL)
351        ObDereferenceObject(pFileObj);
352    return status;
353}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值