Windows8内核模式下开发NDIS应用 NDIS Filter讲解

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               


 在Win8系统下开发驱动程序,需要数字证书,还需要驱动签名认证。不能像XP下面那样疯狂滴耍流氓了。


 由于Win8系统的内核做了大幅度的修改,它和XP系统的内核起了很大的变化,最显著的就是刚才说的:需要签名和证书。  还有就是:不能随意的HOOK SSDT了。




在开发NDIS驱动程序的时候,WDK开发包提供了一个新的框架,叫着NDIS Filter
NDIS Filter是一个例子工程。
假入我把WDK安装在E盘,那么这个工程代码就在:
C:\WinDDK\8600.16385.1\src\network\ndis\filter目录下。


把这个例子工程和原来的Passthru工程代码做比较,您会发现,原来需要导出来的2种类型的回调函数MiniportXXX和ProtocolXXX 在新的框架里面被全部隐藏起来了。
微软提供了新的函数。 一起来看看,微软提供了什么。
在这里,为了方便分析, 我把函数代码都做了功能注释,请大家一起看看。
代码如下:



#pragma NDIS_INIT_FUNCTION(DriverEntry)#define LITTLE_ENDIAN   (1)//// Global variables// NDIS_HANDLE         FilterDriverHandle; // NDIS handle for filter driverNDIS_HANDLE         FilterDriverObject;NDIS_HANDLE         NdisFilterDeviceHandle = NULL;PDEVICE_OBJECT      DeviceObject = NULL;FILTER_LOCK         FilterListLock;LIST_ENTRY          FilterModuleList;PWCHAR              InstanceStrings = NULL;NDIS_FILTER_PARTIAL_CHARACTERISTICS DefaultChars = {
   { 0, 0, 0},      0,      FilterSendNetBufferLists,      FilterSendNetBufferListsComplete,      NULL,      FilterReceiveNetBufferLists,      FilterReturnNetBufferLists};    typedef struct in_addr {
      union {    struct {
     UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;    struct {
     USHORT s_w1,s_w2; } S_un_w;    ULONG S_addr;  } S_un;} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;#pragma push(1)typedef struct IP_HEADER{
    #if LITTLE_ENDIAN  unsigned char  ip_hl:4;    /* 头长度 */  unsigned char  ip_v:4;      /* 版本号 */#else  unsigned char   ip_v:4unsigned char   ip_hl:4;     #endif  unsigned char  TOS;           // 服务类型  unsigned short   TotLen;      // 封包总长度,即整个IP包的长度  unsigned short   ID;          // 封包标识,唯一标识发送的每一个数据报  unsigned short   FlagOff;     // 标志  unsigned char  TTL;           // 生存时间,就是TTL  unsigned char  Protocol;      // 协议,可能是TCP、UDP、ICMP等  unsigned short Checksum;      // 校验和  struct in_addr        iaSrc;  // 源IP地址  struct in_addr        iaDst;  // 目的PI地址}IP_HEADER, *PIP_HEADER;typedef struct tcp_header{
      unsigned short src_port;    //源端口号  unsigned short dst_port;    //目的端口号  unsigned int   seq_no;      //序列号  unsigned int   ack_no;      //确认号#if LITTLE_ENDIAN  unsigned char reserved_1:4; //保留6位中的4位首部长度  unsigned char thl:4;    //tcp头部长度  unsigned char flag:6//6位标志  unsigned char reseverd_2:2; //保留6位中的2位#else  unsigned char thl:4;    //tcp头部长度  unsigned char reserved_1:4; //保留6位中的4位首部长度  unsigned char reseverd_2:2; //保留6位中的2位  unsigned char flag:6//6位标志 #endif  unsigned short wnd_size;   //16位窗口大小  unsigned short chk_sum;    //16位TCP检验和  unsigned short urgt_p;     //16为紧急指针}TCP_HEADER,*PTCP_HEADER;typedef struct udp_header {
      USHORT srcport;   // 源端口  USHORT dstport;   // 目的端口  USHORT total_len; // 包括UDP报头及UDP数据的长度(单位:字节)  USHORT chksum;    // 校验和}UDP_HEADER,*PUDP_HEADER;#pragma push()#define IP_OFFSET                               0x0E//IP 协议类型#define PROT_ICMP                               0x01 #define PROT_TCP                                0x06 #define PROT_UDP                                0x11 USHORT UTIL_htons( USHORT hostshort ){  PUCHAR  pBuffer;  USHORT  nResult;  nResult = 0;  pBuffer = (PUCHAR )&hostshort;  nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00) | (pBuffer[ 1 ] & 0x00FF);  return( nResult );}/*UTIL_ntohs把网络字节顺序转换成主机字节顺序*/USHORT UTIL_ntohs( USHORT netshort )return( UTIL_htons( netshort ) );}NTSTATUS DriverEntry(IN  PDRIVER_OBJECT  DriverObject, IN  PUNICODE_STRING   RegistryPath){    NDIS_STATUS                             Status;    NDIS_FILTER_DRIVER_CHARACTERISTICS      FChars;    NDIS_STRING                             ServiceName;    NDIS_STRING                             UniqueName;    NDIS_STRING                             FriendlyName;    BOOLEAN                                 bFalse = FALSE;    UNREFERENCED_PARAMETER(RegistryPath);        DEBUGP(DL_TRACE,("===>DriverEntry...\n"));       RtlInitUnicodeString(&ServiceName, FILTER_SERVICE_NAME);    RtlInitUnicodeString(&FriendlyName, FILTER_FRIENDLY_NAME);    RtlInitUnicodeString(&UniqueName, FILTER_UNIQUE_NAME);    FilterDriverObject = DriverObject;        do    {        NdisZeroMemory(&FChars, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));  /*大多数的NDIS6.0数据结构中包含的对象头结构的成员,即NDIS_OBJECT_HEADER结构。对象头有三个成员:类型,大小和修改。如果头信息是不正确的,那么调用NDIS6.0函数将失败。*/        FChars.Header.Type =          NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;        FChars.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);        FChars.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;        FChars.MajorNdisVersion = FILTER_MAJOR_NDIS_VERSION;        FChars.MinorNdisVersion = FILTER_MINOR_NDIS_VERSION;        FChars.MajorDriverVersion = 1;        FChars.MinorDriverVersion = 0;        FChars.Flags = 0;        FChars.FriendlyName = FriendlyName;        FChars.UniqueName = UniqueName;        FChars.ServiceName = ServiceName;            /******************************************************NDIS_FILTER_DRIVER_CHARACTERISTICS结构中Mandatory例程******************************************************/        FChars.AttachHandler = FilterAttach;        FChars.DetachHandler = FilterDetach;        FChars.RestartHandler = FilterRestart;        FChars.PauseHandler = FilterPause;/************************************************************NDIS_FILTER_DRIVER_CHARACTERISTICS结构中Optional且不能在运行时变更的例程*************************************************************/        FChars.SetOptionsHandler = FilterRegisterOptions;        FChars.SetFilterModuleOptionsHandler = FilterSetModuleOptions;        FChars.OidRequestHandler = FilterOidRequest;        FChars.OidRequestCompleteHandler = FilterOidRequestComplete;        FChars.StatusHandler = FilterStatus;       FChars.DevicePnPEventNotifyHandler = FilterDevicePnPEventNotify;       FChars.NetPnPEventHandler = FilterNetPnPEvent;            FChars.CancelSendNetBufferListsHandler = FilterCancelSendNetBufferLists;/**************************************************************DIS_FILTER_DRIVER_CHARACTERISTICS结构中Optional且能在运行时变更的例程。        下面这4个例程也被定义在NDIS_FILTER_PARTIAL_CHARACTERISTICS中,这个结构指定的例程可以在运行时的FilterSetModuleOptions例程中调用NdisSetOptionHandles来改变。如果过滤驱动要在例程中修改自身的一个特性,那么必须提供FilterSetModuleOptions例程。****************************************************************/        FChars.SendNetBufferListsHandler = FilterSendNetBufferLists;     FChars.SendNetBufferListsCompleteHandler = FilterSendNetBufferListsComplete;        FChars.ReturnNetBufferListsHandler = FilterReturnNetBufferLists;        FChars.ReceiveNetBufferListsHandler = FilterReceiveNetBufferLists;       ///        FChars.CancelOidRequestHandler = FilterCancelOidRequest;                      DriverObject->DriverUnload = FilterUnload;            FilterDriverHandle = NULL;        FILTER_INIT_LOCK(&FilterListLock);        InitializeListHead(&FilterModuleList);          // 把Filter驱动注册给NDIS        Status = NdisFRegisterFilterDriver(DriverObject,                                           (NDIS_HANDLE)FilterDriverObject,                                           &FChars,                                            &FilterDriverHandle);        if (Status != NDIS_STATUS_SUCCESS)        {            DEBUGP(DL_WARN, ("MSFilter: Register filter driver failed.\n"));             break;        }        //        // Initilize spin locks        //        Status = FilterRegisterDevice();        if (Status != NDIS_STATUS_SUCCESS)        {            NdisFDeregisterFilterDriver(FilterDriverHandle);            FILTER_FREE_LOCK(&FilterListLock);            DEBUGP(DL_WARN, ("MSFilter: Register device for the filter driver failed.\n"));             break;        }            }     while(bFalse);            DEBUGP(DL_TRACE, ("<===DriverEntry, Status = %8x\n", Status));    return Status;    }//过滤驱动注册可选服务NDIS_STATUSFilterRegisterOptions(        IN NDIS_HANDLE  NdisFilterDriverHandle, //它指向了这个过滤驱动        IN NDIS_HANDLE  FilterDriverContext     //它是这个驱动的上下文        ){    DEBUGP(DL_TRACE, ("===>FilterRegisterOptions\n"));        ASSERT(NdisFilterDriverHandle == FilterDriverHandle);    ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);    if ((NdisFilterDriverHandle != (NDIS_HANDLE)FilterDriverHandle) ||        (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject))    {        return NDIS_STATUS_INVALID_PARAMETER;    }    DEBUGP(DL_TRACE, ("<===FilterRegisterOptions\n"));    return (NDIS_STATUS_SUCCESS);}    /***************************************************************  FilterAttach函数的功能:   Attaching状态表示:一个Filter Driver正准备附加一个Filter Module到一个驱动栈上。   一个过滤驱动进入Attaching状态下不能进行发送请求、接收指示、状态指示、OID请求操作。   当一个过滤驱动进入Attaching状态时,它可以:   (1)创建一个环境上下文区域并且初始化一个缓冲区池以及其Filter Module特点的资源。  (2)用NDIS 传来给Filter Attach的NdisFilterHandle作为输入来调用NdisFSetAttributes例程。   Attach is complete   当Filter Module在Attaching状态下并且Filter Driver初始化了所有的Filter Module所需要的   所有资源时,Filter Module进入Paused状态。   参数说明:    NdisFilterHandle     它用于所有过滤驱动中对Ndisxxx类例程的调用时引用指示这个过滤模块。    FilterDriverContext  它由NdisFRegisterFilterDriver的FilterDriverContext来指定。    AttachParameters     它是过滤模块的初始化参数结构体。 **************************************************************/NDIS_STATUSFilterAttach(    IN  NDIS_HANDLE                     NdisFilterHandle,    IN  NDIS_HANDLE                     FilterDriverContext,    IN  PNDIS_FILTER_ATTACH_PARAMETERS  AttachParameters    ){    PMS_FILTER              pFilter = NULL;    NDIS_STATUS             Status = NDIS_STATUS_SUCCESS;    NDIS_FILTER_ATTRIBUTES  FilterAttributes;    ULONG                   Size;    BOOLEAN               bFalse = FALSE;        DEBUGP(DL_TRACE, ("===>FilterAttach: NdisFilterHandle %p\n", NdisFilterHandle));    do    {        ASSERT(FilterDriverContext == (NDIS_HANDLE)FilterDriverObject);        if (FilterDriverContext != (NDIS_HANDLE)FilterDriverObject)        {            Status = NDIS_STATUS_INVALID_PARAMETER;            break;        }                if ((AttachParameters->MiniportMediaType != NdisMedium802_3)                && (AttachParameters->MiniportMediaType != NdisMediumWan))        {           DEBUGP(DL_ERROR, ("MSFilter: Doesn't support media type other than NdisMedium802_3.\n"));                    Status = NDIS_STATUS_INVALID_PARAMETER;           break;        }                Size = sizeof(MS_FILTER) +                AttachParameters->FilterModuleGuidName->Length +                AttachParameters->BaseMiniportInstanceName->Length +                AttachParameters->BaseMiniportName->Length;                pFilter = (PMS_FILTER)FILTER_ALLOC_MEM(NdisFilterHandle, Size);        if (pFilter == NULL)        {            DEBUGP(DL_WARN, ("MSFilter: Failed to allocate context structure.\n"));            Status = NDIS_STATUS_RESOURCES;            break;        }                NdisZeroMemory(pFilter, sizeof(MS_FILTER));        pFilter->FilterModuleName.Length = pFilter->FilterModuleName.MaximumLength = AttachParameters->FilterModuleGuidName->Length;        pFilter->FilterModuleName.Buffer = (PWSTR)((PUCHA
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Filter Drivers主要包括以下特性:   1) 一个Filter Drivers实例叫Filter Module。Filter Module附加在一个适配器的微端口驱动上, 来自相同或不同Filter Drivers的多个Filter Module都可以被堆叠在一个网络适配器上   2) 在Filter Module被安装到驱动栈时,之上的协议驱动和之下的微端口驱动都不需要提供额外的支持功能   3) 因为Filter Module不像中间层驱动(intermediate driver)那样提供一个虚拟的微口,也不与某个设备对象联结,所以在微端口适配器(miniport adapter)之上的Filter Module 功能相当于一个修过过版本的微端口适配器(miniport adapter)。(原文:Because filter drivers do not implement virtual miniports like an intermediate driver, filter drivers are not associated with a device object. A miniport adapter with overlying filter modules functions as a modified version of the miniport adapter.)   4) NDIS使用配置信息来到决定一个Filter Module附加到一个网络适配器栈上的顺序   5) 在不用拆除整驱动栈的情况下,NDIS可以动态的插入、删除Filter Module或进行重新配置   6) 当NDIS重起驱动栈的时候协议驱动可以获得在栈上的Filter Module列表   7) Filter Drivers可以过滤下层网络适配器上绝大部分的通信。Filter Module不联结某特定的绑定(Filter modules are not associated with any particular binding between overlying protocol drivers and the miniport adapter.)   8) Filter Drivers 可以选择为过滤服务也可以选择为分流的不过滤服务,选择为哪一种是可以动态配置的(Filter drivers can select the services that are filtered and can be bypassed for the services that are not filtered. The selection of the services that are bypassed and the services that are filtered can be reconfigured dynamically.)   9) NDIS 保证有效的上下文空间,也不就是说Filter Drivers不要需要通代码COPY缓冲区来获得上下文空间  

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值