• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            旅途

            如果想飛得高,就該把地平線忘掉

            Windows下網(wǎng)絡(luò)數(shù)據(jù)報(bào)的監(jiān)聽和攔截技術(shù)

            Windows下網(wǎng)絡(luò)數(shù)據(jù)報(bào)的監(jiān)聽和攔截技術(shù)1

                    Windows下網(wǎng)絡(luò)數(shù)據(jù)報(bào)的監(jiān)聽和攔截技術(shù)是一個(gè)比較古老的話題,應(yīng)用也很廣泛,例如

            防火墻等等。這篇小文只是對(duì)該技術(shù)的一個(gè)總結(jié),沒有新技術(shù),高手免看:)

                    要監(jiān)聽和攔截Windows下的數(shù)據(jù)報(bào),基本可以在兩個(gè)層次進(jìn)行,一個(gè)是用戶態(tài)(user-mo

            de),一個(gè)是核心態(tài)(kernel-mode)。

                    在用戶態(tài)下,從高到低大概有四種方法。

                    1、原是套結(jié)字(Raw Socket)。Winsock2以后提供了原始套結(jié)字功能,可以在用戶態(tài)用

            Winsock函數(shù)接收所有流經(jīng)Winsock的IP包。這種方法在MSDN里面有敘述,是MS官方支持

            的方法,在網(wǎng)上也有很多資料。但是這種方法只能監(jiān)聽但是不能攔截?cái)?shù)據(jù)報(bào),所以可以

            作為網(wǎng)絡(luò)監(jiān)視器的選擇技術(shù),但是不能實(shí)現(xiàn)防火墻等更高要求的功能。另外最致命的缺

            點(diǎn)就是只能在Winsock層次上進(jìn)行,而對(duì)于網(wǎng)絡(luò)協(xié)議棧中底層協(xié)議的數(shù)據(jù)包例如TDI無法

            進(jìn)行處理。對(duì)于一些木馬和病毒來說很容易避開這個(gè)層次的監(jiān)聽。

                    2、替換系統(tǒng)自帶的WINSOCK動(dòng)態(tài)連接庫。這種方法可以在很多文章里面找到詳細(xì)的實(shí)現(xiàn)

            細(xì)節(jié)。 通過替換系統(tǒng)Winsock庫的部分導(dǎo)出函數(shù),實(shí)現(xiàn)數(shù)據(jù)報(bào)的監(jiān)聽和攔截。缺點(diǎn)同1。

             

                    3、Winsock服務(wù)提供者(SPI)。SPI是Winsock的另一面,是Winsock2的一個(gè)新特性。

            起初的Winsock是圍繞著TCP/IP協(xié)議運(yùn)行的,但是在Winsock 2中卻增加了對(duì)更多傳輸協(xié)

            議的支持。Winsock2不僅提供了一個(gè)供應(yīng)用程序訪問網(wǎng)絡(luò)服務(wù)的Windows socket應(yīng)用程

            序編程接口(API),還包含了由傳輸服務(wù)提供者和名字解析服務(wù)提供者實(shí)現(xiàn)的Winsock

            服務(wù)提供者接口(SPI)和ws2_32.dll。 Winsock 2的傳輸服務(wù)提供者是以動(dòng)態(tài)鏈接庫的

            形式(DLL)存在的。以下是winsock 2在傳輸服務(wù)提供者上的WOSA(Windows開放服務(wù)結(jié)

            構(gòu)):

            ----------------------------

            |Windows socket 2 應(yīng)用程序|

            ----------------------------Windows socket 2 API

            |       WS2_32.DLL        |

            ----------------------------Windows socket 2 傳輸SPI

            |   傳輸服務(wù)提供者(DLL)  |

            ----------------------------

            Windows socket SPI提供三種協(xié)議:分層協(xié)議,基礎(chǔ)協(xié)議和協(xié)議鏈。分層協(xié)議是在基礎(chǔ)

            協(xié)議的上層,依靠底層基礎(chǔ)協(xié)議實(shí)現(xiàn)更高級(jí)的通信服務(wù)。基礎(chǔ)協(xié)議是能夠獨(dú)立,安全地

            和遠(yuǎn)程端點(diǎn)實(shí)現(xiàn)數(shù)據(jù)通信的協(xié)議,它是相對(duì)與分層協(xié)議而言的。協(xié)議鏈?zhǔn)菍⒁幌盗械幕?/p>

            礎(chǔ)協(xié)議和分層協(xié)議按特點(diǎn)的順序連接在一起的鏈狀結(jié)構(gòu),可以通過Platform SDK附帶的

            工具Sporder.exe察看系統(tǒng)已經(jīng)安裝的SPI,請(qǐng)參見下圖:

            API------------------------

               |      WS2_32.DLL     |

            SPI------------------------

               | 分層協(xié)議 |

            SPI-------------

               | 分層協(xié)議 |

            SPI------------------------

               |       基礎(chǔ)協(xié)議       |

               ------------------------

                    每個(gè)應(yīng)用程序通過Ws2_32.dll和相應(yīng)的服務(wù)提供者進(jìn)行嚴(yán)格的數(shù)據(jù)交換。Ws2_32.dl

            l根

            據(jù)應(yīng)用程序在創(chuàng)建套接字時(shí)所提供的參數(shù)來選擇特定的服務(wù)提供者,然后把應(yīng)用程序的

            實(shí)現(xiàn)過程轉(zhuǎn)發(fā)由所選創(chuàng)建套接字的服務(wù)提供者來管理。也就是說,Ws2_32.dll只是一個(gè)

            中間過程,而應(yīng)用程序只是一個(gè)接口,數(shù)據(jù)通信的實(shí)現(xiàn)卻是由服務(wù)提供者來完成的。所

            以我們通過適當(dāng)?shù)脑黾幼约旱姆謱訁f(xié)議服務(wù)提供者,使其位于SPI的頂端,那么就能將W

            s2_32.dll傳給服務(wù)提供者的數(shù)據(jù)報(bào)攔截下來。由于是MS的官方方法,具體的使用方法在

            其Platform SDK里面有詳細(xì)的例子(LSP),在MSDN里面也有詳細(xì)的解釋。這種方法的優(yōu)點(diǎn)

            是能夠獲得調(diào)用Winsock的進(jìn)程的詳細(xì)信息,并能實(shí)現(xiàn)Qos和數(shù)據(jù)加密。所以SPI是用戶態(tài)

            數(shù)據(jù)攔截的較好地點(diǎn)。缺點(diǎn)同1。

                    4、Windows2000包過濾接口。由于過濾規(guī)則限制太多不靈活而應(yīng)用不多。

                    5、網(wǎng)絡(luò)監(jiān)視器SDK。MS官方的實(shí)時(shí)監(jiān)視分析網(wǎng)絡(luò)數(shù)據(jù)的方法。但是由于封裝的太復(fù)?

            櫻?

            使用起來不靈活。

             

                    在核心態(tài)下,數(shù)據(jù)報(bào)的監(jiān)視和攔截方法比較復(fù)雜,由于大多個(gè)人防火墻都是在核心?

            ?

            實(shí)現(xiàn)的,所以在這里比較詳細(xì)的敘述一下。具體的請(qǐng)參見nt/2kDDK文檔。大概有下面幾

            個(gè)方法。

            1、     TDI過濾驅(qū)動(dòng)程序(TDI Filter Driver)。

            2、     NDIS中間層驅(qū)動(dòng)程序(NDIS Intermediate Driver)。編寫IM DRIVER在NDIS中間層

             

             

            對(duì)MINIPORT(網(wǎng)卡驅(qū)動(dòng)程序)和協(xié)議驅(qū)動(dòng)程序之間的數(shù)據(jù)包進(jìn)行攔截。這是微軟提供的

            一種技術(shù)。在DDK中MS提供了Passthru例子,很多中間層過濾驅(qū)動(dòng)都可以由之改編。但編

            寫該過濾程序攔截程序非常的復(fù)雜,安裝也很麻煩。

            3、     Win2k Filter-Hook Driver。

            4、     NDIS Hook Driver。這種方法又有兩種實(shí)現(xiàn)方式。

            (1)向NDIS注冊(cè)假協(xié)議(fake protocol)。這是在協(xié)議層上的處理。在Windows內(nèi)核中

            ,所有已注冊(cè)的協(xié)議是通過一個(gè)單向的協(xié)議鏈表來維護(hù)的。這個(gè)單向鏈表保存了所有已

            注冊(cè)協(xié)議的NDIS_PROTOCOL_BLOCK結(jié)構(gòu)的地址,在這個(gè)結(jié)構(gòu)中保存了協(xié)議驅(qū)動(dòng)所指定的相

            應(yīng)的派發(fā)函數(shù)的地址如RECEIVE_HANDLER等。

            struct _NDIS_PROTOCOL_BLOCK

            {

            PNDIS_OPEN_BLOCK OpenQueue; // queue of opens for this protocol

            REFERENCE Ref; // contains spinlock for OpenQueue

            UINT Length; // of this NDIS_PROTOCOL_BLOCK struct

            NDIS50_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics;// handler addresses

             

            struct _NDIS_PROTOCOL_BLOCK * NextProtocol; // Link to next

            ULONG MaxPatternSize;

            #if defined(NDIS_WRAPPER)

            //

            // Protocol filters

            //

            struct _NDIS_PROTOCOL_FILTER * ProtocolFilter[NdisMediumMax+1];

            WORK_QUEUE_ITEM WorkItem; // Used during NdisRegisterProtocol to

            // notify protocols of existing drivers.

            KMUTEX Mutex; // For serialization of Bind/Unbind requests

            PKEVENT DeregEvent; // Used by NdisDeregisterProtocol

            #endif

            };

            typedef struct _NDIS_PROTOCOL_BLOCK NDIS_PROTOCOL_BLOCK, *PNDIS_PROTOCOL_BLO

            CK;并且,每個(gè)協(xié)議驅(qū)動(dòng)還對(duì)應(yīng)一個(gè)NDIS_OPEN_BLOCK的單向鏈表來維護(hù)其所綁定的網(wǎng)卡

            信息。當(dāng)協(xié)議驅(qū)動(dòng)調(diào)用NdisRegisterProtocol之后,

            EXPORT

            VOID

            NdisRegisterProtocol(

            OUT PNDIS_STATUS Status,

            OUT PNDIS_PROTOCOL_BLOCK NdisProtocolHandle, /*注意NDIS_HANDLE所指向的就是PN

            DIS_PROTOCOL_BLOCK的結(jié)構(gòu),不要有什么懷疑。*/

            IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics,

            IN UINT CharacteristicsLength

            );

            NDIS總是會(huì)把新注冊(cè)的協(xié)議放在協(xié)議鏈表的表頭并返回這張表,所以只要我們注冊(cè)一個(gè)

            新的協(xié)議通過新協(xié)議注冊(cè)返回的鏈表頭就可以輕而易舉的遍歷系統(tǒng)中所有協(xié)議表。但是

            ,如果要成功地掛接派發(fā)函數(shù),還需要對(duì)協(xié)議所對(duì)應(yīng)的NDIS_OPEN_BLOCK結(jié)構(gòu)里的派發(fā)函

            數(shù)進(jìn)行掛接,因?yàn)镹DIS并不是直接調(diào)用協(xié)議驅(qū)動(dòng)在NDIS_PROTOCOL_CHARACTERISTICS所注

            冊(cè)的派發(fā)函數(shù)地址,而是調(diào)用NDIS_OPEN_BLOCK里的派發(fā)函數(shù)。

            struct _NDIS_OPEN_BLOCK

            {

            PNDIS_MAC_BLOCK MacHandle; // pointer to our MAC

            NDIS_HANDLE MacBindingHandle; // context when calling MacXX funcs

            PNDIS_ADAPTER_BLOCK AdapterHandle; // pointer to our adapter

            PNDIS_PROTOCOL_BLOCK ProtocolHandle; // pointer to our protocol

            NDIS_HANDLE ProtocolBindingContext;// context when calling ProtXX funcs

            PNDIS_OPEN_BLOCK AdapterNextOpen; // used by adapter's OpenQueue

            PNDIS_OPEN_BLOCK ProtocolNextOpen; // used by protocol's OpenQueue

            PFILE_OBJECT FileObject; // created by operating system

            BOOLEAN Closing; // TRUE when removing this struct

            BOOLEAN Unloading; // TRUE when processing unload

            BOOLEAN NoProtRsvdOnRcvPkt; // Reflect the protocol_options

            NDIS_HANDLE CloseRequestHandle; // 0 indicates an internal close

            KSPIN_LOCK SpinLock; // guards Closing

            PNDIS_OPEN_BLOCK NextGlobalOpen;

            //

            // These are optimizations for getting to MAC routines. They are not

            // necessary, but are here to save a dereference through the MAC block.

            //

            SEND_HANDLER SendHandler;

            TRANSFER_DATA_HANDLER TransferDataHandler;

            //

            // These are optimizations for getting to PROTOCOL routines. They are not

            // necessary, but are here to save a dereference through the PROTOCOL block.

             

            //

            SEND_COMPLETE_HANDLER SendCompleteHandler;

            TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;

            RECEIVE_HANDLER ReceiveHandler;

            RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler;

            //

            // Extentions to the OPEN_BLOCK since Product 1.

            //

            RECEIVE_HANDLER PostNt31ReceiveHandler;

            RECEIVE_COMPLETE_HANDLER PostNt31ReceiveCompleteHandler;

            //

            // NDIS 4.0 extensions

            //

            RECEIVE_PACKET_HANDLER ReceivePacketHandler;

            SEND_PACKETS_HANDLER SendPacketsHandler;

            //

            // More NDIS 3.0 Cached Handlers

            //

            RESET_HANDLER ResetHandler;

            REQUEST_HANDLER RequestHandler;

            //

            // Needed for PnP

            //

            UNICODE_STRING AdapterName; // Upcased name of the adapter we are bound to

            };

            這張表是一個(gè)單向鏈接表,并且存放了和PNDIS_OPEN_BLOCK->ProtocolCharacteristic

            s

            一樣的數(shù)據(jù)收發(fā)派發(fā)函數(shù),當(dāng)?shù)贜塊網(wǎng)卡發(fā)送數(shù)據(jù)包到第N個(gè)協(xié)議時(shí),就會(huì)調(diào)用第N個(gè)協(xié)議

            與第N個(gè)網(wǎng)卡之間建立的

            NDIS_OPEN_BLOCK表里的SendHandler或SendPacketHandler。所以我們還需要對(duì)這張表里

            的派發(fā)函數(shù)進(jìn)行處理(勾掛)。

            值得注意的是,在Windows9x/Me/NT的DDK中,NDIS_PROTOCOL_BLOCK的定義是很明確的,

            而在Windows 2000/xp的DDK中,并沒有該結(jié)構(gòu)的詳細(xì)定義,也就是說該結(jié)構(gòu)在Windows2

            000/xp下是非公開的,因此開發(fā)人員需要利用各種調(diào)試工具來發(fā)掘該結(jié)構(gòu)的詳細(xì)定義。

            也正是因?yàn)槿绱耍@種方法對(duì)平臺(tái)的依賴性比較大,需要在程序中判斷不同的操作系統(tǒng)

            版本而使用不同的結(jié)構(gòu)定義。可以用NdisOpenProtocolConfiguration打開協(xié)議配置,用

            NdisReadConfiguration查詢NDIS版本。

            下面的函數(shù)注冊(cè)fake protocol并將PNDIS_PROTOCOL_BLOCK結(jié)構(gòu)存在ProtHandle中NDIS_

            HANDLE GetProtocolBlock()

            {

                    NDIS_PROTOCOL_CHARACTERISTICS   PChars;

                    NDIS_STRING                                             Name;

                    NDIS_HANDLE                                             ProtHandle;

                    NDIS_STATUS                                             Status;

                    NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

                    PChars.MajorNdisVersion = 5;

                    PChars.MinorNdisVersion = 0;

                    NdisInitUnicodeString(&Name, L"WssFW"); // Protocol name

                    PChars.Name = Name;

                    PChars.OpenAdapterCompleteHandler = NULL;

                    PChars.CloseAdapterCompleteHandler = NULL;

                    PChars.SendCompleteHandler = NULL;

                    PChars.TransferDataCompleteHandler = NULL;

             

                    PChars.ResetCompleteHandler = NULL;

                    PChars.RequestCompleteHandler = NULL;

                    PChars.ReceiveHandler = NULL;

                    PChars.ReceiveCompleteHandler = NULL;

                    PChars.StatusHandler = NULL;

                    PChars.StatusCompleteHandler = NULL;

                    PChars.BindAdapterHandler = NULL;

                    PChars.UnbindAdapterHandler = NULL;

                    PChars.UnloadHandler = NULL;

                    PChars.ReceivePacketHandler = NULL;

                    PChars.PnPEventHandler= NULL;

                    NdisRegisterProtocol(&Status,

                                                             &ProtHandle,

                                                             &PChars,

                                                             sizeof(NDIS_PROTOCOL_CHARACTERIS

            TICS));

                    ASSERT(Status == NDIS_STATUS_SUCCESS);

                    if(Status == NDIS_STATUS_SUCCESS)

                            return ProtHandle;

                    else

                            return NULL;

            }

                    下面的函數(shù)掛接PNDIS_PROTOCOL_BLOCK中PNDIS_PROTOCOL_CHARACTERISTICS結(jié)構(gòu)的R

            ec

            eiveHandler和ReceivePacketHandler

            PVOID

            HookProtoFunc(

                                      PNDIS_PROTOCOL_CHARACTERISTICS pCharacteristics,

                                      DWORD dwFunctionCode,

                                      PVOID pfuncNew,

                                      DWORD dwNdisVersion)

            {

                    PVOID pOldFunc = NULL;

                    //Check parameters

                    if( (!pCharacteristics ) || (!pfuncNew) )

                            return NULL;

                    switch(dwFunctionCode)

                    {

                    case PROTO_RECEIVE_HANDLER:

                            //Just hook once!

                            if(pCharacteristics->ReceiveHandler != pfuncNew )

                            {

                                    pOldFunc = pCharacteristics->ReceiveHandler;

                                    if( pOldFunc )

                                            pCharacteristics->ReceiveHandler = pfuncNew;

                            }

                            break;

                    case PROTO_RECEIVE_PACKET_HANDLER:

                            if(pCharacteristics->ReceivePacketHandler != pfuncNew)

                            {

                                    //if pOpenBlock is NULL or pOpenBlock->ReceivePacketHandl

            er is NULL,

                                    //just hook Characteristics;

                                    pOldFunc = pCharacteristics->ReceivePacketHandler;

                                    if(pOldFunc)

                                            pCharacteristics->ReceivePacketHandler = pfuncNew

            ;

                            }

                            break;

                    default:

                            break;

                    }

                    return pOldFunc;

            }

            下面的函數(shù)掛接PNDIS_OPEN_BLOCK結(jié)構(gòu)里的ReceiveHandler和ReceivePacketHandler

            PVOID

            HookBlockFunc(

                                      PNDIS_OPEN_BLOCK pFirstOpenBlock,

                                      DWORD dwFunctionCode,

                                      PVOID pfuncNew,

                                      DWORD dwNdisVersion)

            {

                    RECEIVE_HANDLER * pReceiveHandler = NULL;

                    RECEIVE_PACKET_HANDLER * pReceivePacketHandler = NULL;

            //      PVOID pFuncHandler = NULL;

                    PVOID pOldFunc = NULL;

                    PNDIS_OPEN_BLOCK pOpenBlock = pFirstOpenBlock;

                    if(!pFirstOpenBlock)

                            return NULL;

                    if(!pfuncNew )

                            return NULL;

                    switch(dwFunctionCode)

                    {

                    case PROTO_RECEIVE_HANDLER:

                            //travel all NDIS_OPEN_BLOCK

                            for(;pOpenBlock;pOpenBlock = GetNextBlock( pOpenBlock,dwNdisVersi

            on ))

                            {

                                    pReceiveHandler = GetReceiveHandler(pOpenBlock,dwNdisVers

            ion);

                                    //Just hook once!

                                    if( *pReceiveHandler != pfuncNew )

                                    {

                                            pOldFunc = *pReceiveHandler;

                                            *pReceiveHandler = pfuncNew;

                                    }

                                    if(dwNdisVersion == 0x00040001)//win2k ????

                                    {

                                            pReceiveHandler = GetPostNt31ReceiveHandler(pOpen

            Block,dwNdisVersion);

                                            if( *pReceiveHandler != pfuncNew )

                                            {

                                                    pOldFunc = *pReceiveHandler;

                                                    *pReceiveHandler = pfuncNew;

                                            }

                                    }

                            }

                            break;

                    case PROTO_RECEIVE_PACKET_HANDLER:

                            //travel all NDIS_OPEN_BLOCK

                            for(;pOpenBlock;pOpenBlock = GetNextBlock( pOpenBlock,dwNdisVersi

            on ))

                                    pReceivePacketHandler = GetReceivePacketHandler( pOpenBlo

            ck,dwNdisVersion

             );

                                    //Just hook once !

                                    if(*pReceivePacketHandler != pfuncNew)

                                    {

                                            pOldFunc = *pReceivePacketHandler;

                                            *pReceivePacketHandler = pfuncNew;

                                    }

                            }

                            break;

             

                    default:

                            break;

                    }

                    return pOldFunc;

            }


            bsp;          &PChars,

                                                             sizeof(NDIS_PROTOCOL_CHARACTERIS

            TICS));

                    ASSERT(Status == NDIS_STATUS_SUCCESS);

                    if(Status == NDIS_STATUS_SUCCESS)

                            return ProtHandle;

                    else

                            return NULL;

            }

                    下面的函數(shù)掛接PNDIS_PROTOCOL_BLOCK中PNDIS_PROTOCOL_CHARACTERISTICS結(jié)構(gòu)的R

            ec

            eiveHandler和ReceivePacketHandler

            PVOID

            HookProtoFunc(

                                      PNDIS_PROTOCOL_CHARACTERISTICS pCharacteristics,

                                      DWORD dwFunctionCode,

                                      PVOID pfuncNew,

                                      DWORD dwNdisVersion)

            {

                    PVOID pOldFunc = NULL;

                    //Check parameters

                    if( (!pCharacteristics ) || (!pfuncNew) )

                            return NULL;

                    switch(dwFunctionCode)

                    {

                    case PROTO_RECEIVE_HANDLER:

                            //Just hook once!

                            if(pCharacteristics->ReceiveHandler != pfuncNew )

                            {

                                    pOldFunc = pCharacteristics->ReceiveHandler;

                                    if( pOldFunc )

                                            pCharacteristics->ReceiveHandler = pfuncNew;

                            }

                            break;

                    case PROTO_RECEIVE_PACKET_HANDLER:

                            if(pCharacteristics->ReceivePacketHandler != pfuncNew)

                            {

                                    //if pOpenBlock is NULL or pOpenBlock->ReceivePacketHandl

            er is NULL,

                                    //just hook Characteristics;

                                    pOldFunc = pCharacteristics->ReceivePacketHandler;

                                    if(pOldFunc)

                                            pCharacteristics->ReceivePacketHandler = pfuncNew

            ;

                            }

                            break;

                    default:

                            break;

                    }

                    return pOldFunc;

            }

            下面的函數(shù)掛接PNDIS_OPEN_BLOCK結(jié)構(gòu)里的ReceiveHandler和ReceivePacketHandler

            PVOID

            HookBlockFunc(

                                      PNDIS_OPEN_BLOCK pFirstOpenBlock,

                                      DWORD dwFunctionCode,

                                      PVOID pfuncNew,

                                      DWORD dwNdisVersion)

            {

                    RECEIVE_HANDLER * pReceiveHandler = NULL;

                    RECEIVE_PACKET_HANDLER * pReceivePacketHandler = NULL;

            //      PVOID pFuncHandler = NULL;

                    PVOID pOldFunc = NULL;

                    PNDIS_OPEN_BLOCK pOpenBlock = pFirstOpenBlock;

                    if(!pFirstOpenBlock)

                            return NULL;

                    if(!pfuncNew )

                            return NULL;

                    switch(dwFunctionCode)

                    {

                    case PROTO_RECEIVE_HANDLER:

                            //travel all NDIS_OPEN_BLOCK

                            for(;pOpenBlock;pOpenBlock = GetNextBlock( pOpenBlock,dwNdisVersi

            on ))

                            {

                                    pReceiveHandler = GetReceiveHandler(pOpenBlock,dwNdisVers

            ion);

                                    //Just hook once!

                                    if( *pReceiveHandler != pfuncNew )

                                    {

                                            pOldFunc = *pReceiveHandler;

                                            *pReceiveHandler = pfuncNew;

                                    }

                                    if(dwNdisVersion == 0x00040001)//win2k ????

                                    {

                                            pReceiveHandler = GetPostNt31ReceiveHandler(pOpen

            Block,dwNdisVersion);

                                            if( *pReceiveHandler != pfuncNew )

                                            {

                                                    pOldFunc = *pReceiveHandler;

                                                    *pReceiveHandler = pfuncNew;

                                            }

                                    }

                            }

                            break;

                    case PROTO_RECEIVE_PACKET_HANDLER:

                            //travel all NDIS_OPEN_BLOCK

                            for(;pOpenBlock;pOpenBlock = GetNextBlock( pOpenBlock,dwNdisVersi

            on ))

                                    pReceivePacketHandler = GetReceivePacketHandler( pOpenBlo

            ck,dwNdisVersion

             );

                                    //Just hook once !

                                    if(*pReceivePacketHandler != pfuncNew)

                                    {

                                            pOldFunc = *pReceivePacketHandler;

                                            *pReceivePacketHandler = pfuncNew;

                                    }

                            }

                            break;

             

                    default:

                            break;

                    }

                    return pOldFunc;

            }


            bsp;          &PChars,

                                                             sizeof(NDIS_PROTOCOL_CHARACTERIS

            TICS));

                    ASSERT(Status == NDIS_STATUS_SUCCESS);

                    if(Status == NDIS_STATUS_SUCCESS)

                            return ProtHandle;

                    else

                            return NULL;

            }

                    下面的函數(shù)掛接PNDIS_PROTOCOL_BLOCK中PNDIS_PROTOCOL_CHARACTERISTICS結(jié)構(gòu)的R

            ec

            eiveHandler和ReceivePacketHandler

            PVOID

            HookProtoFunc(

                                      PNDIS_PROTOCOL_CHARACTERISTICS pCharacteristics,

                                      DWORD dwFunctionCode,

                                      PVOID pfuncNew,

                                      DWORD dwNdisVersion)

            {

                    PVOID pOldFunc = NULL;

                    //Check parameters

                    if( (!pCharacteristics ) || (!pfuncNew) )

                            return NULL;

                    switch(dwFunctionCode)

                    {

                    case PROTO_RECEIVE_HANDLER:

                            //Just hook once!

                            if(pCharacteristics->ReceiveHandler != pfuncNew )

                            {

                                    pOldFunc = pCharacteristics->ReceiveHandler;

                                    if( pOldFunc )

                                            pCharacteristics->ReceiveHandler = pfuncNew;

                            }

                            break;

                    case PROTO_RECEIVE_PACKET_HANDLER:

                            if(pCharacteristics->ReceivePacketHandler != pfuncNew)

                            {

                                    //if pOpenBlock is NULL or pOpenBlock->ReceivePacketHandl

            er is NULL,

                                    //just hook Characteristics;

                                    pOldFunc = pCharacteristics->ReceivePacketHandler;

                                    if(pOldFunc)

                                            pCharacteristics->ReceivePacketHandler = pfuncNew

            ;

                            }

                            break;

                    default:

                            break;

                    }

                    return pOldFunc;

            }

            下面的函數(shù)掛接PNDIS_OPEN_BLOCK結(jié)構(gòu)里的ReceiveHandler和ReceivePacketHandler

            PVOID

            HookBlockFunc(

                                      PNDIS_OPEN_BLOCK pFirstOpenBlock,

                                      DWORD dwFunctionCode,

                                      PVOID pfuncNew,

                                      DWORD dwNdisVersion)

            {

                    RECEIVE_HANDLER * pReceiveHandler = NULL;

                    RECEIVE_PACKET_HANDLER * pReceivePacketHandler = NULL;

            //      PVOID pFuncHandler = NULL;

                    PVOID pOldFunc = NULL;

                    PNDIS_OPEN_BLOCK pOpenBlock = pFirstOpenBlock;

                    if(!pFirstOpenBlock)

                            return NULL;

                    if(!pfuncNew )

                            return NULL;

                    switch(dwFunctionCode)

                    {

                    case PROTO_RECEIVE_HANDLER:

                            //travel all NDIS_OPEN_BLOCK

                            for(;pOpenBlock;pOpenBlock = GetNextBlock( pOpenBlock,dwNdisVersi

            on ))

                            {

                                    pReceiveHandler = GetReceiveHandler(pOpenBlock,dwNdisVers

            ion);

                                    //Just hook once!

                                    if( *pReceiveHandler != pfuncNew )

                                    {

                                            pOldFunc = *pReceiveHandler;

                                            *pReceiveHandler = pfuncNew;

                                    }

                                    if(dwNdisVersion == 0x00040001)//win2k ????

                                    {

                                            pReceiveHandler = GetPostNt31ReceiveHandler(pOpen

            Block,dwNdisVersion);

                                            if( *pReceiveHandler != pfuncNew )

                                            {

                                                    pOldFunc = *pReceiveHandler;

                                                    *pReceiveHandler = pfuncNew;

                                            }

                                    }

                            }

                            break;

                    case PROTO_RECEIVE_PACKET_HANDLER:

                            //travel all NDIS_OPEN_BLOCK

                            for(;pOpenBlock;pOpenBlock = GetNextBlock( pOpenBlock,dwNdisVersi

            on ))

                                    pReceivePacketHandler = GetReceivePacketHandler( pOpenBlo

            ck,dwNdisVersion

             );

                                    //Just hook once !

                                    if(*pReceivePacketHandler != pfuncNew)

                                    {

                                            pOldFunc = *pReceivePacketHandler;

                                            *pReceivePacketHandler = pfuncNew;

                                    }

                            }

                            break;

             

                    default:

                            break;

                    }

                    return pOldFunc;

            }


            posted on 2007-07-29 15:02 旅途 閱讀(1827) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)技術(shù)

            国产∨亚洲V天堂无码久久久| 久久综合中文字幕| 无码人妻久久一区二区三区免费| 伊人久久大香线蕉亚洲| 日韩久久久久久中文人妻| 99久久伊人精品综合观看| 亚洲伊人久久成综合人影院 | 亚洲&#228;v永久无码精品天堂久久| 武侠古典久久婷婷狼人伊人| 亚洲∧v久久久无码精品| 久久久久久国产精品无码下载| 亚洲一级Av无码毛片久久精品| 无码人妻久久久一区二区三区| 国产精品嫩草影院久久| 午夜精品久久久久久99热| 久久人人超碰精品CAOPOREN| 久久国产热精品波多野结衣AV| 欧美成人免费观看久久| 久久综合综合久久97色| 国内精品久久久久影院优| 综合久久一区二区三区 | 91亚洲国产成人久久精品网址| 中文无码久久精品| 国产精品久久久久久久久久影院| 狠狠色综合久久久久尤物| 亚洲综合久久综合激情久久| 99久久99久久久精品齐齐| 色欲久久久天天天综合网 | 久久国产精品77777| 日韩人妻无码精品久久免费一| 亚洲国产成人精品91久久久| 久久狠狠一本精品综合网| 久久国产香蕉一区精品| 久久精品中文字幕一区| 理论片午午伦夜理片久久| 久久久久无码专区亚洲av| 人妻无码精品久久亚瑟影视| 日日狠狠久久偷偷色综合免费| 一级女性全黄久久生活片免费 | 国产精品无码久久综合网| 精品久久久久中文字|