• 细节解密NDIS协议驱动为什么能捕获到发送包


    NDIS Loopback Discussion

    http://www.ndis.com/ndis-ndis5/loopback/loopback.htm

    Looping Back NDIS Packets

    http://msdn.microsoft.com/en-us/library/ff557071.aspx

    ============================================================

    XP2环境下的具体流程:

    tcpip调用ndissend的时候

    //////////////////////////////////////////

    ndissend(miniport,mypacket)

    {

    )//这个标志貌似是协议驱动设置混杂模式就会设置上的,上面标志说明中提到,如果一个miniport有多个protocol绑定,只要有有其中一个就会设置上

    if(miniport->flag&check_for_loopback)

       {

          ndisMLoopbackPacketX( miniport, mypacket)

       }

    }

    ////////////////////////////

    ndisMLoopbackPacketX( miniport, mypacket)

    {

      if ((mypacket->Private.NdisPacketFlags & 0x20)//20= fPACKET_ALREADY_LOOPEDBACK

         { return ;}

       ndis_packet * new_packet=NULL;

    //ndisMIsLoopbackPacket会申请一个新的new_packet

         is_LOOPBACK_ONLY = ndisMIsLoopbackPacket((_NDIS_MINIPORT_BLOCK *)miniport_block, (_NDIS_PACKET *)mypacket, &new_packet);

        if (new_packet)

          {

        if ( pMini_block->MediaType != 7 )          // 7=NdisMediumArcnet878_2

        {

          确定要loopback上去了,加上20=fPACKET_ALREADY_LOOPEDBACK标志,说明已  经处理过了

          mypacket->Private.NdisPacketFlags |= 0x20u;

      

          ethFilterDprIndicateReceivePacket(miniport_block, new_packet);

          } 

         returnis_LOOPBACK_ONLY ;

    }

    ////////////////////=================================================================

    char __fastcall ndisMIsLoopbackPacket(_NDIS_MINIPORT_BLOCK *pMini_block, _NDIS_PACKET *ori_packet, _NDIS_PACKET **pNewPacket)

    {

       //里面会有目标地址是否为自身的判断,略过!

        v7 = pMini_block2->MediaType;

      if ( !v7 )                                    // mediatype =0   means NdisMedium802_3

      {

         判断

       if ( !(BYTE2(pMini_block2->Flags) & 0x80) ) // 80,其实就是flags的800000标志,对应着SEND_LOOPBACK_DIRECTED

       {}

      else{

         //一般情况下都是这个分支,说明miniport一般都设置了SEND_LOOPBACK_DIRECTED这个标志位

         判断下包里面的MAC地址是不是本机的MAC地址,我们需要的情况是MAC地址不同

        申请一个新包pNewPacket,把ori_packet数据copy到pNewPacket

            if ( pNewPacket )

            {

              *pNewPacket = pNewPacket_allocated;//pNewPacket_allocated在前面已经copy好数据

              pNewPacket_allocated->Private.NdisPacketFlags |= 2u;// 会多了fPACKET_IS_LOOPBACK, fPACKET_CLEAR_ITEMS这2个属性

              pNewPacket_allocated->Private.Flags = v27->Private.Flags & 0x80 | 0x100;

            }                                       // 80就是DONT_LOOPBACK,但这里是与操作,如果原来没的话,也不会加上

                                                    // 100=IS_LOOPBACK_PACKET标明是loopback包

     

         return 0;

         }

     }

    }

     PS:如果你想你发送的包不给捕获,很简单,只要把你的包加上DONT_LOOPBACK标志即可,默认是无这个标志的

    ////////////////////////////////

    ethFilterDprIndicateReceivePacket(miniport_block, new_packet)

    {

        miniport_filter_header = mini_block->EthDB //_X_FILTER类型,这个_X_FILTER结构有NumOpens字段,标志有多少个协议绑定了它

    //pBindInfo是_X_BINDING_INFO类型,

             for ( pBindInfo = miniport_filter_header->OpenList; pBindInfo; pBindInfo = v89 )

          {

            v89 = pBindInfo->NextOpen; //取对应的_NDIS_OPEN_BLOCK

             if ( !(pkt1->Private.Flags & 0x80)      // // 80好像是DONT_LOOPBACK

            {

               v65 = pBindInfo->PacketFilters;

                 v66 = (unsigned __int8)(v65 & 0xA0) == 0;// a0就是NDIS_PACKET_TYPE_ALL_LOCAL和NDIS_PACKET_TYPE_PROMISCUOUS的组合

                                                    // 这里取值的来源是bindinfo链表,里面每个对应一个绑定信息,说明是针对指定设定的协议驱动,例如A驱动的设置成NDIS_PACKET_TYPE_PROMISCUOUS

                                                    // 但如果B协议驱动不设置NDIS_PACKET_TYPE_PROMISCUOUS的话,B协议驱动不能接收到。

              v92 = v65 & 0xA0;

              if ( v66 )                            // 一些其它的协议会跳走。。例如TCP/IP,所以不会重复接收到发送出去的包

                                                    // 

                                                    // 测试改了tcpip的这个标志位为0x8b后,tcpip!arprecv回调也能接收到发送出去的包,修改之前是不能的

              {                                     // 

                                                    // 在我把wireshark协议驱动的这个_X_BINDING_INFO->PacketFilters改为0xb后。

                                                    // 由于0xb&a0==0,所以改了之后,就收不到发送出去的包了。但还是能收到外部发来的包,

                                                    // 因为发送和接收的包indicate的路径不一样,前者是直接在send的时候判断是否要loopback就直接indicate了

                JUMPOUT(v96, 8u, *(unsigned int *)loc_22FB1);//不符合就循环跳过。。例子中就是tcpip协议驱动不会接收到(出现JUMPOUT,是因为IDA识别函数的范围不准确)

             }

               //条件满足0xA0,调用协议驱动的接收例程,像wireshark为什么能截获发送包就是因为这里的调用了wireshark的协议驱动的ReceiveHandler

          openblock = pBindInfo->NdisBindingHandle

            openblock->ReceiveHandler(   )

             }

    }

    XP环境,粗略F5,粗略动态跟踪,不保证无错

  • 相关阅读:
    hdu2574 Hdu Girls' Day (分解质因数)
    python------logging模块
    python之异常
    python之反射
    python面向对象之封装
    python之面向对象2
    pyhton之路---面向对象
    python之路模块与包
    python常用模块
    匿名函数
  • 原文地址:https://www.cnblogs.com/kkindof/p/2542320.html
Copyright © 2020-2023  润新知