当前位置: 首页 > news >正文

细节解密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,粗略动态跟踪,不保证无错

转载于:https://www.cnblogs.com/kkindof/archive/2012/06/08/2542320.html

相关文章:

  • Geofence是什么
  • 语音的前置处理(一)
  • 关于成都局2012年春运期间客票预售期调整的通知
  • 经典JavaScript正则表达式实战
  • [转载]给网游写一个挂吧(二) – 启动外挂上
  • 2012/6/19
  • Metro AppBarButtonStyles中按钮样式名称收集
  • [译]Kinect for Windows SDK开发入门(三):基础知识 下
  • 到底应该怎么样才能用上dropbox?
  • 优秀开发工具:推荐8个在线调试代码的网站
  • 应届生本人面试经历
  • IOS基本框架
  • sql 分割字符串
  • 六边形网格快速定位
  • OD调试实例1
  • 收藏网友的 源程序下载网
  • Laravel 实践之路: 数据库迁移与数据填充
  • Meteor的表单提交:Form
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Theano - 导数
  • Vue2.0 实现互斥
  • windows下使用nginx调试简介
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 机器学习中为什么要做归一化normalization
  • 记一次删除Git记录中的大文件的过程
  • 前端面试题总结
  • 首页查询功能的一次实现过程
  • 数组大概知多少
  • 通信类
  • 由插件封装引出的一丢丢思考
  • 在Unity中实现一个简单的消息管理器
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • $$$$GB2312-80区位编码表$$$$
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (C语言)字符分类函数
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (数据结构)顺序表的定义
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .NET Core 2.1路线图
  • .net core webapi 大文件上传到wwwroot文件夹
  • .Net Web窗口页属性
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • /bin/rm: 参数列表过长"的解决办法
  • @Autowired @Resource @Qualifier的区别
  • [.net]官方水晶报表的使用以演示下载
  • [AIGC] Spring Interceptor 拦截器详解