久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

WinDDK自帶的 Passthru NDIS網(wǎng)絡(luò)中間層驅(qū)動(dòng) 學(xué)習(xí)

 tuohuang0303 2011-04-05

中間層驅(qū)動(dòng)下面連接ndis miniport驅(qū)動(dòng),,上面連接ndis protocol驅(qū)動(dòng) ,,可以監(jiān)控所有本機(jī)收到的和發(fā)出去的網(wǎng)絡(luò)包,。自己寫一個(gè)NDIS Intermediate Driver (中間層驅(qū)動(dòng))     可以過濾網(wǎng)絡(luò)包實(shí)現(xiàn)類似防火墻的功能(我不知道那些防火墻是不是這樣做的,,好像都是去寫NDIS Hook Drivers,,而不是這個(gè)),,也可以修改網(wǎng)絡(luò)包,,可以用來做VPN等功能(實(shí)際VPN客戶端可能不一定是這樣做的,,不過確實(shí)有人寫了類似的實(shí)例),。

      有上圖可以知道中間層是包括protocol和虛擬miniport兩部分的,因?yàn)槲易约鹤隽艘粋€(gè)arp防欺騙工具,,所以像寫一個(gè)這樣的驅(qū)動(dòng)來截取本機(jī)收到的ARP包,。因?yàn)榍懊娌捎胣dis protocol驅(qū)動(dòng)來獲取arp包也是可以的,但同時(shí)在發(fā)送ARP包的時(shí)候,可能是handle有沖突,,我自己弄不好同步問題,,索性再寫個(gè)中間層驅(qū)動(dòng)算了。參考WinDDK自帶的 Passthru例子,,稍加修改就可以達(dá)到目的,。我想捕獲本機(jī)收到的ARP包,所以只要修改protocol.c 中的PtReceivePacket()函數(shù)就可以了,,本機(jī)收到網(wǎng)絡(luò)包的時(shí)候系統(tǒng)是會(huì)自動(dòng)回調(diào)這個(gè)函數(shù)的,,我只要在這里過濾ARP包然后轉(zhuǎn)發(fā)給自己的應(yīng)用程序就行了。不過好像說是底層有的miniport不支持直接提交packet上來,,所以也有可能是通過PtReceive()這個(gè)函數(shù)提交數(shù)據(jù),。所以也要改一下這個(gè)函數(shù)才行。我實(shí)際測(cè)試的時(shí)候也是有時(shí)是在PtReceivePacket()中得到數(shù)據(jù),,有時(shí)是在PtReceive()得到數(shù)據(jù)的,。所以最后兩個(gè)都改一下吧。如果像過濾本機(jī)發(fā)出去的網(wǎng)絡(luò)包,,那么看miniport那部分就行了,。不過我沒有做了,我只是想得到本機(jī)收到的ARP包而已了,。

改后的PtReceivePacket()函數(shù)如下,,其他的修改如PtReceive,還有就是和用戶態(tài)應(yīng)用程序交互IO控制相應(yīng)那些,,ARP包結(jié)構(gòu)等就不細(xì)說了,。


INT
PtReceivePacket(
     IN NDIS_HANDLE             ProtocolBindingContext,
     IN PNDIS_PACKET            Packet
     )
/*++

Routine Description:

     ReceivePacket handler. Called by NDIS if the miniport below supports
     NDIS 4.0 style receives. Re-package the buffer chain in a new packet
     and indicate the new packet to protocols above us. Any context for
     packets indicated up must be kept in the MiniportReserved field.

     NDIS 5.1 - packet stacking - if there is sufficient "stack space" in
     the packet passed to us, we can use the same packet in a receive
     indication.

Arguments:

     ProtocolBindingContext - Pointer to our adapter structure.
     Packet - Pointer to the packet

Return Value:

     == 0 -> We are done with the packet
     != 0 -> We will keep the packet and call NdisReturnPackets() this
             many times when done.
--*/
{
     PADAPT               pAdapt =(PADAPT)ProtocolBindingContext;
     NDIS_STATUS          Status;
     PNDIS_PACKET         MyPacket;
     BOOLEAN              Remaining;
//----------------------
      ULONG      readPacketBufferLength;
//-----------------------

 

     //
     // Drop the packet silently if the upper miniport edge isn't initialized or
     // the miniport edge is in low power state
     //
     if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))
     {
           return 0;
     }

 

///-----widebright增加的 過濾 ARP包的 段----------------------------------------------------------------------------
      DBGPRINT(("PtReceivePacket Function   \n")); //////////////////////////////////////////////////////////
          GetPktPayload(Packet,                             // Copy payload
                   &recARPPacket,                         //    to area.
                   sizeof(recARPPacket),                       // Amount of space in area.
                   &readPacketBufferLength                        // Return number of bytes in packet.
                  );
      
    if (readPacketBufferLength !=0)
    {
           if (recARPPacket.ehhdr.eh_type ==   1544)       // #define EPT_ARP 0x0806    1544= htons(EPT_ARP)   就是看是不是ARP包
     {
            DBGPRINT(("PtReceivePacket Function   and ARP packet \n")); //////////////////////////////////////////////////////////
                         if (pEvent)
                        KeSetEvent(pEvent, 0, 0);    //通知應(yīng)用程序收到ARP 包了
     }
    }


          //如果return 0 則表示丟棄 包,不傳給上一層

///-----widebright增加的 過濾 ARP包的 段----------------------------------------------------------------------------

 

 

#ifdef NDIS51
     //
     // Check if we can reuse the same packet for indicating up.
     // See also: PtReceive().
     //
     (VOID)NdisIMGetCurrentPacketStack(Packet, &Remaining);
     if (Remaining)
     {
         //
         // We can reuse "Packet". Indicate it up and be done with it.
         //
         Status = NDIS_GET_PACKET_STATUS(Packet);
         NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);
         return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
     }
#endif // NDIS51

     //
     // Get a packet off the pool and indicate that up
     //
     NdisDprAllocatePacket(&Status,
                            &MyPacket,
                            pAdapt->RecvPacketPoolHandle);

     if (Status == NDIS_STATUS_SUCCESS)
     {
         PRECV_RSVD             RecvRsvd;

         RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
         RecvRsvd->OriginalPkt = Packet;

         NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);
         NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);

         //
         // Get the original packet (it could be the same packet as the one
         // received or a different one based on the number of layered miniports
         // below) and set it on the indicated packet so the OOB data is visible
         // correctly to protocols above us.
         //
         NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));

         //
         // Set Packet Flags
         //
         NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

         Status = NDIS_GET_PACKET_STATUS(Packet);

         NDIS_SET_PACKET_STATUS(MyPacket, Status);
         NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));

         if (pAdapt->MiniportHandle != NULL)
         {
             NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);
         }

         //
         // Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
         // NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
         // it might have changed! Use the value saved in the local variable.
         //
         if (Status == NDIS_STATUS_RESOURCES)
         {
             //
             // Our ReturnPackets handler will not be called for this packet.
             // We should reclaim it right here.
             //
             NdisDprFreePacket(MyPacket);
         }

         return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
     }
     else
     {
         //
         // We are out of packets. Silently drop it.
         //
         return(0);
     }
}

 

可以看到我增加的代碼是很少的,, GetPktPayload是一個(gè)從別人的代碼里面抄過來的,,從packet結(jié)構(gòu)讀取包緩存的函數(shù)。一并轉(zhuǎn)貼出來吧,,如下:

/**************************************************************************************************/      
/*                                                                                                 */      
/* Copy the payload of the specified packet into the specified buffer.                             */      
/*                                                                                                 */      
/* Adapted from http://www./papers/ndispacket/readonpacket.htm, 12 May 2003.               */      
/*                                                                                                 */      
/**************************************************************************************************/      

VOID
GetPktPayload(
               PNDIS_PACKET      pPacket,                // Address of packet descriptor.
               PUCHAR            pOutBfr,                // Address of output buffer, to get copied packet payload.
               ULONG             ulOutBfrAvail,          // Size of output buffer.
               PULONG            pUlBytesCopied          // Output variable for number of bytes copied.
              )
{
    PNDIS_BUFFER     pNdisBfr;
    ULONG            ulBfrCnt,
                    ulTotPktLen,
                    ulCurrBfr,
                    ulAmtToMove;
    PUCHAR           pCurrBfr;

    *pUlBytesCopied = 0;                                // Set 0 bytes copied.

    if (0==ulOutBfrAvail)                               // Is output buffer 0 bytes in length?
      goto Done;

    NdisQueryPacket(pPacket,                            // Get information from packet descriptor.
                    NULL,                      
                    NULL,
                    &pNdisBfr,                          // Output variable for address of first buffer descriptor.
                    &ulTotPktLen                        // Output variable for number of bytes in packet payload.
                   );

    NdisQueryBuffer(pNdisBfr,                           // Get information from first buffer descriptor.
                    &pCurrBfr,                          // Output variable for address of described virtual area.
                    &ulCurrBfr                          // Output variable for size of virtual area.
                   );

    while (ulOutBfrAvail>0)                             // Space remaining in output buffer?
      {
       while (0==ulCurrBfr)                             // While the current buffer has zero length.
         {
          NdisGetNextBuffer(pNdisBfr,                   // Get next buffer descriptor.
                            &pNdisBfr
                           );

          if (NULL==pNdisBfr)                           // None?
            goto Done;

          NdisQueryBuffer(pNdisBfr,                     // Get information from next buffer descriptor.
                          &pCurrBfr,                    // Output variable for address of current buffer.
                          &ulCurrBfr                    // Output variable for size of current buffer.
                         );
         }

       if (ulCurrBfr>ulOutBfrAvail)                     // Does current buffer's usable size exceed space remaining in output buffer?
         ulAmtToMove = ulOutBfrAvail;                   // Use only amount remaining in output buffer.
       else
         ulAmtToMove = ulCurrBfr;                       // Use full size of current buffer.

       NdisMoveMemory(pOutBfr,                          // Copy packet data to output buffer.
                      pCurrBfr,
                      ulAmtToMove
                     );

       *pUlBytesCopied += ulAmtToMove;                  // Update output variable of bytes copied.
       pOutBfr += ulAmtToMove;                          // Update pointer to output buffer.
       ulOutBfrAvail -= ulAmtToMove;                    // Update number of bytes available in output buffer.

       ulCurrBfr = 0;                                   // Force search for next buffer.
      }                                                 // End 'while' copy bytes to output buffer.

Done:
   ;
}

 

這就是獲取ARP 包的關(guān)鍵代碼了,。如果像過濾 TCP/IP包其實(shí)也是要修改一點(diǎn)點(diǎn)就行了。

要什么其他的功能自己動(dòng)手吧,,我也是看了一下MSDN的參考而已,,不甚明白。

自己動(dòng)手豐衣足食,!  


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多