Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6628164
  • 博文数量: 227
  • 博客积分: 10047
  • 博客等级: 上将
  • 技术积分: 6678
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-11 10:33
个人简介

网上的蜘蛛

文章分类

全部博文(227)

文章存档

2010年(19)

2009年(29)

2008年(179)

分类: C/C++

2010-04-19 22:52:21

今天我们来看看如何拷贝NBL中的数据。有时候需要更改数据包中的某些数据,就需要用到此功能(能直接在原来的nBL上更改,然后发送吗?)。

 

  1. 新建一个NBL作为你自己要存放拷贝数据的结构:
    C代码 
    1. pCopyNBL = allocateNetBuffAndNetBufferList(pFilter, dataLength);//Defined by self  
     这个其实是一个自定义的函数,用来分配一个空的NBL.具体代码见后面~
  2. 这里考虑有很多个NBL,而且每个NB中包含多个MDL.所以拿到原始NBL的第一个NB
    C代码 
    1. pCurrentNB = NET_BUFFER_LIST_FIRST_NB(pCurrentNBL);//The first NB  
     再得到第一个NB的第一个MDL:
    C代码 
    1. pMDL = NET_BUFFER_FIRST_MDL(pCurrentNB);  
     最后得到MDL中有用数据:包括分析offset,以及dataLength,起始地址等:
    C代码 
    1. mdlOffset = NET_BUFFER_DATA_OFFSET(pCurrentNB);//I am not sure  
    2. ...  
    3.  NdisQueryMdl( pMDL,(PVOID *)&pData,&dataBufferLength,NormalPagePriority);  
    4.                 if(pData == NULL)  
    5.                 {  
    6.                     DEBUGP(DL_TEST,("pData is NULL ---Fail \n"));  
    7.                     break;  
    8.                 }  
     
  3. 同理我们得到我们自定义NBL中的MDL(只有一个),同时拿到起始地址:
    C代码 
    1. pCopyMDL  =  NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(pCopyNBL));  
    2. ....  
    3. NdisQueryMdl(pCopyMDL,(PVOID *)&pNewBuffer, &newBufferLength,NormalPagePriority);  
    4.             if(pNewBuffer == NULL)  
    5.             {  
    6.                 DEBUGP(DL_TEST,("pNewBuffer is NULL ---Fail \n"));  
    7.                 break;  
    8.             }  
     
  4. 然后把pData的数据拷贝到pNewBuffer中,这里注意拷贝的长度:
    Cpp代码 
    1. bytesToCopy = dataBufferLength - mdlOffset;  
    2.                 if(bytesToCopy > newBufferLength)  
    3.                 {  
    4.                     bytesToCopy = newBufferLength;  
    5.                 }  
    6.                 NdisMoveMemory((pNewBuffer + offset),(pData + mdlOffset), bytesToCopy);//copy data  
    7.                 newBufferLength -= bytesToCopy;  
    8.                 offset += bytesToCopy;  
    9.                 mdlOffset = 0;//CurrentMdlOffset is used only for the first Mdl processed. For the remaining Mdls, it is 0.  
     这里mdlOffset=0,是指以后以后连续的MDL中没有unused 数据。就是整个MDL中的数据都是我们要的。
  5. 然后循环这个NB中所有的MDL.每个NB拷贝完之后,设置NB的datalength:
    C代码 
    1. NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pCopyNBL)) = dataLength;  
    2. pCopyNBL->SourceHandle = pCurrentNBL->SourceHandle;  
     
  6. 循环所有的NBL,把每个NBL串起来:
    Java代码 
    1. if(pNewNetBufferLists == NULL)  
    2.         {  
    3.             pNewNetBufferLists = pCopyNBLTail = pCopyNBL;  
    4.         }  
    5.         else  
    6.         {  
    7.             NET_BUFFER_LIST_NEXT_NBL(pCopyNBLTail) = pCopyNBL;  
    8.         }  
    9.   
    10.         pCurrentNBL = NET_BUFFER_LIST_NEXT_NBL(pCurrentNBL);  
     
  7. 结束拷贝~附上NBL分配函数代码:
    C代码 
    1. PNET_BUFFER_LIST allocateNetBuffAndNetBufferList(  
    2.     IN  PMS_FILTER pFilter,  
    3.     IN  ULONG BufferSize  
    4. )  
    5. {  
    6.     PMDL  pMDL =  NULL;  
    7.     PUCHAR pMDLAddress =NULL;  
    8.     PNET_BUFFER_LIST pNetBufferList = NULL;  
    9.     DEBUGP(DL_TEST,("==============>allocateNetBuffAndNetBufferList\n"));  
    10.     pMDLAddress = (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,BufferSize,FILTER_ALLOC_TAG, LowPoolPriority);  
    11.     NdisZeroMemory(pMDLAddress, BufferSize);  
    12.     do  
    13.     {  
    14.         pMDL = NdisAllocateMdl(pFilter->FilterHandle, pMDLAddress, BufferSize);  
    15.         if(pMDL == NULL)  
    16.         {  
    17.             DEBUGP(DL_TEST,("PMDL Fail....\n"));  
    18.             break;  
    19.         }  
    20.   
    21.         pNetBufferList = NdisAllocateNetBufferAndNetBufferList(  
    22.                              pFilter->SendNetBufferListPool,  
    23.                              sizeof(FILTER_SEND_NETBUFLIST_RSVD), //Request control offset delta  
    24.                              0,           // back fill size  
    25.                              pMDL,  
    26.                              0,          // Data offset  
    27.                              BufferSize);  
    28.         if(pNetBufferList == NULL)  
    29.         {  
    30.             NdisFreeMdl(pMDL);  
    31.             break;  
    32.         }  
    33.     }  
    34.     while(FALSE);  
    35.     DEBUGP(DL_TEST,("<==============allocateNetBuffAndNetBufferList\n"));  
    36.     return pNetBufferList;  
    37. }  
     需要注意分配MDL,一定要使用NdisAllocateMemoryWithTagPriority分配一个空间地址~
  8. 最后是检查是否拷贝正确,参考了这里的代码(打印部分自行添加~):

    基于NDIS Filter 抓包:

  9. 效果图:
这是浏览百度的
下面是浏览javaeye
还有一些疑问:除了程序编译的时候还有三个Warning.就是好像我只考虑了每个NBL中只有一个NB的情况~可能还需要更多的测试~

参考: 

 

阅读(5616) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~