// //Protocol Wrapper Version 1.05 //Author: gjp //email: [email protected] // #include "NdisHook.h" #include "HookRule.h" #pragma pack(push) #pragma pack(1) typedef struct _HOOK_CONTEXT_STRUCT { //runtime code ubyte code1_0x58; //0x58 | pop eax | pop caller IP from stack to eax ubyte code2_0x68; //0x68 | push IMM | push our hook context address struct _HOOK_CONTEXT_STRUCT *m_pHookContext;//point this ubyte code3_0x50; //0x50 | push eax | push caller IP from eax to stack ubyte code4_0xE9; //0xE9 | jmp HookProc | jump our hook proc udword m_pHookProcOffset; //our context data PVOID m_pOriginalProc; PVOID m_pHookProc; PVOID m_pBindAdaptHandle; PVOID m_pProtocolContent; PVOID *m_ppOriginPtr; struct _HOOK_CONTEXT_STRUCT *m_pHookNext; }HOOK_CONTEXT_STRUCT; #pragma pack(pop) HOOK_CONTEXT_STRUCT *m_pOurAllOfHookContext = NULL; dword m_IsFilterEnabled = FALSE; NDIS_HANDLE m_ourPacketPoolHandle = NULL; NDIS_HANDLE m_ourBufferPoolHandle = NULL; PNDIS_PACKET m_ourPacketHandle = NULL; PNDIS_BUFFER m_ourBufferHandle = NULL; PVOID m_ourBuffer = NULL; void ReadPacket(PNDIS_PACKET Packet,PVOID pBuffer,udword dwBufSize); uword wswap(uword value); void HookUnload(void) { ReleaseHookFunc(); if( m_ourBufferHandle ) { NdisFreeBuffer(m_ourBufferHandle); m_ourBufferHandle = NULL; } if( m_ourBuffer ) { NdisFreeMemory(m_ourBuffer,MAX_PACKET_SIZE,0); m_ourBuffer = NULL; } if( m_ourPacketHandle ) { NdisFreePacket(m_ourPacketHandle); m_ourPacketHandle = NULL; } if( m_ourBufferPoolHandle ) { NdisFreeBufferPool(m_ourBufferPoolHandle); m_ourBufferPoolHandle = NULL; } if( m_ourPacketPoolHandle ) { NdisFreePacketPool(m_ourPacketPoolHandle); m_ourPacketPoolHandle = NULL; } return; } dword HookInit(void) { NTSTATUS status; m_ourPacketPoolHandle = NULL; NdisAllocatePacketPool(&status,&m_ourPacketPoolHandle,0xFFF,0x10); if( status != NDIS_STATUS_SUCCESS ) return FALSE; m_ourBufferPoolHandle = NULL; NdisAllocateBufferPool(&status,&m_ourBufferPoolHandle,0x10); if( status != NDIS_STATUS_SUCCESS ) return FALSE; m_ourBuffer = NULL; status = NdisAllocateMemoryWithTag(&m_ourBuffer,MAX_PACKET_SIZE,'NAMW'); if( status != NDIS_STATUS_SUCCESS ) return FALSE; m_ourBufferHandle = NULL; NdisAllocateBuffer(&status,&m_ourBufferHandle,m_ourBufferPoolHandle,m_ourBuffer,MAX_PACKET_SIZE); if( status != NDIS_STATUS_SUCCESS ) return FALSE; m_ourPacketHandle = NULL; NdisAllocatePacket(&status,&m_ourPacketHandle,m_ourPacketPoolHandle); if( status != NDIS_STATUS_SUCCESS ) return FALSE; NdisChainBufferAtFront(m_ourPacketHandle,m_ourBufferHandle); return TRUE; } typedef struct _NDIS41_PROTOCOL_CHARACTERISTICS { #ifdef __cplusplus NDIS40_PROTOCOL_CHARACTERISTICS Ndis40Chars; #else NDIS40_PROTOCOL_CHARACTERISTICS; #endif // // Start of NDIS 4.1 extensions. // CO_SEND_COMPLETE_HANDLER CoSendCompleteHandler; CO_STATUS_HANDLER CoStatusHandler; CO_RECEIVE_PACKET_HANDLER CoReceivePacketHandler; CO_REQUEST_HANDLER CoRequestHandler; CO_REQUEST_COMPLETE_HANDLER CoRequestCompleteHandler; } NDIS41_PROTOCOL_CHARACTERISTICS; dword HookProtocol(void) { //Default ndis version is 5.0 NDIS_PROTOCOL_CHARACTERISTICS ourNPC; NDIS_STRING protoName = NDIS_STRING_CONST("HdFw_Slot"); NDIS_STATUS Status; NDIS_HANDLE ourProtocolHandle = NULL; byte *ProtocolChain; dword offset; dword len; // NDIS_PROTOCOL_BLOCK *pNdisBlock = NULL; // pNdisBlock = pNdisBlock->NextProtocol; // pNdisBlock->NextProtocol = NULL; memset(&ourNPC,0,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); if( m_dwMajorVersion == 0x03 ) { len = sizeof(NDIS30_PROTOCOL_CHARACTERISTICS); //We must need at least ndis version 3.10 ourNPC.MajorNdisVersion = 0x03; ourNPC.MinorNdisVersion = 0x0A; } else if( m_dwMajorVersion == 0x04 ) { len = sizeof(NDIS40_PROTOCOL_CHARACTERISTICS); ourNPC.MajorNdisVersion = 0x04; ourNPC.MinorNdisVersion = 0x00; } else { //treat as version 5.0 len = sizeof(NDIS50_PROTOCOL_CHARACTERISTICS); ourNPC.MajorNdisVersion = 0x05; ourNPC.MinorNdisVersion = 0x00; } ourNPC.Name = protoName; ourNPC.OpenAdapterCompleteHandler = PtOpenAdapterComplete; ourNPC.CloseAdapterCompleteHandler = PtCloseAdapterComplete; ourNPC.SendCompleteHandler = PtSendComplete; ourNPC.TransferDataCompleteHandler = PtTransferDataComplete; ourNPC.ResetCompleteHandler = PtResetComplete; ourNPC.RequestCompleteHandler = PtRequestComplete; ourNPC.ReceiveHandler = PtReceive; ourNPC.ReceiveCompleteHandler = PtReceiveComplete; ourNPC.StatusHandler = PtStatus; ourNPC.StatusCompleteHandler = PtStatusComplete; ourNPC.BindAdapterHandler = PtBindAdapter; ourNPC.UnbindAdapterHandler = PtUnbindAdapter; ourNPC.UnloadHandler = PtUnload; ourNPC.ReceivePacketHandler = PtReceivePacket; ourNPC.PnPEventHandler = PtPNPHandler; NdisRegisterProtocol(&Status,&ourProtocolHandle,&ourNPC,len); if( !NT_SUCCESS(Status) || ourProtocolHandle == NULL ) return FALSE; //NdisRegisterProtocol return hand reference of NDIS_PROTOCOL_BLOCK; ProtocolChain = (byte *)ourProtocolHandle; while(1) { DebugInfoCount++; //Obtain pointer to next protocol link. if( m_dwMajorVersion == 0x03 ) offset = 4; else if( m_dwMajorVersion == 0x04 ) { if( m_dwMinorVersion == 0x01 ) offset = 0x8C; else offset = 0x60; } else if( m_dwMajorVersion == 0x05 ) //NDIS_PROTOCOL_BLOCK->NextProtocol offset = 0x10; else //Error break; ProtocolChain = ((byte **)(ProtocolChain + offset))[0]; if( ProtocolChain == NULL ) break; HookFuncBlock(ProtocolChain); } if( m_dwMajorVersion != 4 ) NdisDeregisterProtocol(&Status,ourProtocolHandle); else { // ((byte *)ourProtocolHandle)[0x0C] = 0x01; // NdisDeregisterProtocol(&Status,ourProtocolHandle); } return TRUE; } // ProtocolContent // Version NextChain offset NDIS_PROTOCOL_CHARACTERISTICS offset BindingAdaptHandle offset // NDIS 3.XX 0x04 0x14 0x08 // NDIS 4.XX 0x60 0x14 0x00 // NDIS 4.01 0x8C 0x14 0x00 // NDIS 5.XX 0x10 0x14 0x00 //----- VOID HookProtocolSendPackets( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE MiniportAdapterContext, IN PPNDIS_PACKET PacketArray, IN UINT NumberOfPackets ); NDIS_STATUS HookProtocolWanSend( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE MacBindingHandle, IN NDIS_HANDLE LinkHandle, IN PVOID Packet ); NDIS_STATUS HookProtocolSend( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE MacBindingHandle, IN PNDIS_PACKET Packet ); NDIS_STATUS HookProtocolReceive( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookaheadBufferSize, IN UINT PacketSize ); NDIS_STATUS HookWanReceive( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE NdisLinkHandle, IN PUCHAR Packet, IN ULONG PacketSize ); INT HookProtocolReceivePacket( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet ); VOID HookBindAdapterHandler( IN HOOK_CONTEXT_STRUCT *pOurContext, OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2); VOID HookSendComplete( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status ); void ReleaseHookFunc(void) { HOOK_CONTEXT_STRUCT *pHookContext,*pNext; pHookContext = m_pOurAllOfHookContext; m_pOurAllOfHookContext = NULL; while(pHookContext) { pNext = pHookContext->m_pHookNext; pHookContext->m_ppOriginPtr[0] = pHookContext->m_pOriginalProc; ExFreePool(pHookContext); pHookContext = pNext; } return; } HOOK_CONTEXT_STRUCT *IsHookedNdisFunc(PVOID pAddr) { HOOK_CONTEXT_STRUCT *pHookContext; pHookContext = m_pOurAllOfHookContext; while(pHookContext) { if( pHookContext == pAddr ) break; pHookContext = pHookContext->m_pHookNext; } return pHookContext; } HOOK_CONTEXT_STRUCT *IsHookedNdisFuncEx(PVOID *pAddr) { HOOK_CONTEXT_STRUCT *pHookContext; pHookContext = m_pOurAllOfHookContext; while(pHookContext) { if( pHookContext->m_ppOriginPtr == pAddr ) break; pHookContext = pHookContext->m_pHookNext; } return pHookContext; } HOOK_CONTEXT_STRUCT *HookNdisFunc(PVOID pHookProc,PVOID *ppOrigProc,PVOID pBindAdaptHandle,PVOID pProtocolContent) { HOOK_CONTEXT_STRUCT *pHookContext; PVOID OrgFunc; pHookContext = IsHookedNdisFunc(ppOrigProc[0]); if( pHookContext ) OrgFunc = pHookContext->m_pOriginalProc; else OrgFunc = ppOrigProc[0]; if( OrgFunc == NULL ) return NULL; pHookContext = IsHookedNdisFuncEx(ppOrigProc); if( pHookContext ) return pHookContext; pHookContext = ExAllocatePoolWithTag(NonPagedPool,sizeof(HOOK_CONTEXT_STRUCT),'HCSP'); if( pHookContext == NULL ) return NULL; memset(pHookContext,0,sizeof(HOOK_CONTEXT_STRUCT)); pHookContext->code1_0x58 = 0x58; pHookContext->code2_0x68 = 0x68; pHookContext->code3_0x50 = 0x50; pHookContext->code4_0xE9 = 0xE9; pHookContext->m_pHookContext = pHookContext; pHookContext->m_pHookProcOffset = ((udword)pHookProc) - (((udword)&pHookContext->m_pHookProcOffset) + sizeof(udword)); pHookContext->m_pBindAdaptHandle = pBindAdaptHandle; pHookContext->m_pProtocolContent = pProtocolContent; pHookContext->m_pOriginalProc = OrgFunc;//ppOrigProc[0]; pHookContext->m_ppOriginPtr = ppOrigProc; pHookContext->m_pHookProc = pHookProc; pHookContext->m_pHookNext = m_pOurAllOfHookContext; m_pOurAllOfHookContext = pHookContext; ppOrigProc[0] = pHookContext; return pHookContext; } typedef struct _NDIS40_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 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; // // Needed for PnP // UNICODE_STRING AdapterName; // Upcased name of the adapter we are bound to }NDIS40_OPEN_BLOCK,*PNDIS40_OPEN_BLOCK; void HookFuncBlock(byte *ProtocolContent) { PNDIS_PROTOCOL_CHARACTERISTICS pProChar; dword IsWan; NDIS_STRING WanString = NDIS_STRING_CONST("NDISWAN"); NDIS_STRING DeviceWanString = NDIS_STRING_CONST("//DEVICE//NDISWAN"); NDIS_STRING TcpipString = NDIS_STRING_CONST("Tcpip"); NDIS_STRING TcpArpString = NDIS_STRING_CONST("TCPIP_WANARP"); NDIS_STRING RasArpString = NDIS_STRING_CONST("RASARP"); if( ProtocolContent == NULL ) return; //Get pointer to NDIS_PROTOCOL_CHARACTERISTICS from protocol content pProChar = (PNDIS_PROTOCOL_CHARACTERISTICS)(ProtocolContent + 0x14); if( KeGetCurrentIrql() == PASSIVE_LEVEL ) { //Check protocol name whether is Wan Lan protocol so that we can correctly hook our function if( !RtlCompareUnicodeString(&pProChar->Name,&WanString,TRUE) || !RtlCompareUnicodeString(&pProChar->Name,&DeviceWanString,TRUE) ) { IsWan = 1; } else IsWan = 0; //We r only interest in following protocol if( !(!RtlCompareUnicodeString(&pProChar->Name,&TcpipString,TRUE) || !RtlCompareUnicodeString(&pProChar->Name,&TcpArpString,TRUE) || !RtlCompareUnicodeString(&pProChar->Name,&RasArpString,TRUE)) ) { return; } } else IsWan = 0; // if( !IsWan ) { HookNdisFunc(HookProtocolReceive,(PVOID *)&pProChar->ReceiveHandler,NULL,ProtocolContent); //{{added by gjp 6.24 // __asm int 3; // HookNdisFunc(HookSendComplete,(PVOID *)&pProChar->SendCompleteHandler,NULL,ProtocolContent); //}} } else HookNdisFunc(HookWanReceive,(PVOID *)&pProChar->WanReceiveHandler,NULL,ProtocolContent); if(pProChar->MajorNdisVersion > 0x03 ) { HookNdisFunc(HookProtocolReceivePacket,(PVOID *)&pProChar->ReceivePacketHandler,NULL,ProtocolContent); HookNdisFunc(HookBindAdapterHandler,(PVOID *)&pProChar->BindAdapterHandler,NULL,ProtocolContent); } //pProChar->Name; //We should obtain and save BindAdaptHandle in order to pass it to NdisTransferData //BindAdaptHandle is pNdisOpenBlock if( m_dwMajorVersion == 0x05 ) { PNDIS_OPEN_BLOCK pNdisOpenBlock; pNdisOpenBlock = ((PNDIS_OPEN_BLOCK *)ProtocolContent)[0]; while(pNdisOpenBlock) { //__asm int 3; if( !IsWan ) { HookNdisFunc(HookProtocolSend,(PVOID *)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolReceive,(PVOID *)&pNdisOpenBlock->PostNt31ReceiveHandler,pNdisOpenBlock,ProtocolContent); //{{added by gjp 6.24 // __asm int 3; // HookNdisFunc(HookSendComplete,(PVOID *)&pNdisOpenBlock->SendCompleteHandler,pNdisOpenBlock,ProtocolContent); //}} } else { HookNdisFunc(HookProtocolWanSend,(PVOID *)&pNdisOpenBlock->WanSendHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookWanReceive,(PVOID *)&pNdisOpenBlock->WanReceiveHandler,pNdisOpenBlock,ProtocolContent); } HookNdisFunc(HookProtocolReceive,(PVOID *)&pNdisOpenBlock->ReceiveHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolReceivePacket,(PVOID *)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolSendPackets,(PVOID *)&pNdisOpenBlock->SendPacketsHandler,pNdisOpenBlock,ProtocolContent); pNdisOpenBlock = pNdisOpenBlock->ProtocolNextOpen; } } else if( m_dwMajorVersion == 0x04 ) { PNDIS40_OPEN_BLOCK pNdisOpenBlock; pNdisOpenBlock = ((PNDIS40_OPEN_BLOCK *)ProtocolContent)[0]; while(pNdisOpenBlock) { if( !IsWan ) { HookNdisFunc(HookProtocolSend,(PVOID *)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolReceive,(PVOID *)&pNdisOpenBlock->PostNt31ReceiveHandler,pNdisOpenBlock,ProtocolContent); } else { HookNdisFunc(HookProtocolWanSend,(PVOID *)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookWanReceive,(PVOID *)&pNdisOpenBlock->PostNt31ReceiveHandler,pNdisOpenBlock,ProtocolContent); } HookNdisFunc(HookProtocolReceive,(PVOID *)&pNdisOpenBlock->ReceiveHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolReceivePacket,(PVOID *)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent); HookNdisFunc(HookProtocolSendPackets,(PVOID *)&pNdisOpenBlock->SendPacketsHandler,pNdisOpenBlock,ProtocolContent); pNdisOpenBlock = (PNDIS40_OPEN_BLOCK)pNdisOpenBlock->ProtocolNextOpen; } // HookNdisFunc(HookProtocolReceivePacket,(PVOID *)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent); } else if( m_dwMajorVersion == 0x03 ) {//Unknown information of ndis3.0 NDIS_OPEN_BLOCK struct } return; } void CheckSendHandle(HOOK_CONTEXT_STRUCT *pOurContext) { HOOK_CONTEXT_STRUCT *pHookContext; if( pOurContext == NULL || pOurContext->m_pBindAdaptHandle == NULL ) return; if( m_dwMajorVersion == 5 ) { PNDIS_OPEN_BLOCK pNdisOpenBlock; pNdisOpenBlock = (PNDIS_OPEN_BLOCK)pOurContext->m_pBindAdaptHandle; pHookContext = (HOOK_CONTEXT_STRUCT *)pNdisOpenBlock->SendHandler; if( pHookContext ) { if( !(pHookContext->m_ppOriginPtr == (PVOID *)&pNdisOpenBlock->SendHandler && pHookContext->m_pHookProc == (PVOID)HookProtocolSend) ) { pHookContext = IsHookedNdisFuncEx((PVOID *)&pNdisOpenBlock->SendHandler); if( pHookContext ) { if( pHookContext->m_pOriginalProc == (PVOID)pNdisOpenBlock->SendHandler) { pNdisOpenBlock->SendHandler = (SEND_HANDLER)pHookContext; } } } } pHookContext = (HOOK_CONTEXT_STRUCT *)pNdisOpenBlock->SendPacketsHandler; if( pHookContext ) { if( !(pHookContext->m_ppOriginPtr == (PVOID *)&pNdisOpenBlock->SendPacketsHandler && pHookContext->m_pHookProc == (PVOID)HookProtocolSendPackets) ) { pHookContext = IsHookedNdisFuncEx((PVOID *)&pNdisOpenBlock->SendPacketsHandler); if( pHookContext ) { if( pHookContext->m_pOriginalProc == (PVOID)pNdisOpenBlock->SendPacketsHandler) { pNdisOpenBlock->SendPacketsHandler = (SEND_PACKETS_HANDLER)pHookContext; } } } } } else if( m_dwMajorVersion == 4 ) { PNDIS40_OPEN_BLOCK pNdisOpenBlock; pNdisOpenBlock = (PNDIS40_OPEN_BLOCK)pOurContext->m_pBindAdaptHandle; pHookContext = (HOOK_CONTEXT_STRUCT *)pNdisOpenBlock->SendHandler; if( pHookContext ) { if( !(pHookContext->m_ppOriginPtr == (PVOID *)&pNdisOpenBlock->SendHandler && pHookContext->m_pHookProc == (PVOID)HookProtocolSend) ) { pHookContext = IsHookedNdisFuncEx((PVOID *)&pNdisOpenBlock->SendHandler); if( pHookContext ) { if( pHookContext->m_pOriginalProc == (PVOID)pNdisOpenBlock->SendHandler) { pNdisOpenBlock->SendHandler = (SEND_HANDLER)pHookContext; } } } } pHookContext = (HOOK_CONTEXT_STRUCT *)pNdisOpenBlock->SendPacketsHandler; if( pHookContext ) { if( !(pHookContext->m_ppOriginPtr == (PVOID *)&pNdisOpenBlock->SendPacketsHandler && pHookContext->m_pHookProc == (PVOID)HookProtocolSendPackets) ) { pHookContext = IsHookedNdisFuncEx((PVOID *)&pNdisOpenBlock->SendPacketsHandler); if( pHookContext ) { if( pHookContext->m_pOriginalProc == (PVOID)pNdisOpenBlock->SendPacketsHandler) { pNdisOpenBlock->SendPacketsHandler = (SEND_PACKETS_HANDLER)pHookContext; } } } } } return; } dword HookFilterBuffer(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer,udword PacketSize,dword isOutgoing) { NTSTATUS status; dword result = TRUE; switch(wswap(((PETHHDR)pBuffer)->h_proto)) { case ETH_P_IP: { if( isOutgoing ) TotalSendBytes += PacketSize; else TotalReceiveBytes += PacketSize; TotalIPPackets++; result = AnalyzeIP( (PIPHdr)(&((byte *)pBuffer)[sizeof(ETHHDR)]),PacketSize - sizeof(ETHHDR), isOutgoing); break; } case ETH_P_ARP: TotalARPPackets++; break; case ETH_P_RARP: break; default: TotalOtherPackets++; break; } return result; } dword HookFilterReceivePacket(HOOK_CONTEXT_STRUCT *pOurContext,udword TotalPacketSize,PVOID pHeadBuffer,udword dwHeadSize,PNDIS_PACKET pPacket,dword isOutgoing) { dword PacketSize; PVOID pBuffer = NULL; NTSTATUS status; PNDIS_BUFFER firstBuffer,nextBuffer; dword result = TRUE; byte *pBuf; NdisQueryPacket(pPacket,NULL,NULL,NULL,&PacketSize); if( /*!PacketSize ||*/ PacketSize + dwHeadSize < sizeof(ETHHDR) ) return TRUE; status = NdisAllocateMemoryWithTag(&pBuffer,PacketSize + dwHeadSize,'NAMW'); if( status != NDIS_STATUS_SUCCESS || pBuffer == NULL ) return TRUE;//FALSE; //obtain content from the packet pBuf = (byte *)pBuffer; NdisMoveMemory(pBuf,pHeadBuffer,dwHeadSize); ReadPacket(pPacket,&pBuf[dwHeadSize],PacketSize); result = HookFilterBuffer(pOurContext,pBuffer,TotalPacketSize + dwHeadSize,isOutgoing); NdisFreeMemory(pBuffer,PacketSize + dwHeadSize,0); return result; } // Filter Packet // return 0 = block this packet dword HookFilterPacket(HOOK_CONTEXT_STRUCT *pOurContext,PNDIS_PACKET pPacket,dword isOutgoing) { dword PacketSize; PVOID pBuffer = NULL; NTSTATUS status; PNDIS_BUFFER firstBuffer,nextBuffer; dword result = TRUE; NdisQueryPacket(pPacket,NULL,NULL,NULL,&PacketSize); if( /*!PacketSize ||*/ PacketSize < sizeof(ETHHDR) ) return TRUE; status = NdisAllocateMemoryWithTag(&pBuffer,PacketSize,'NAMW'); if( status != NDIS_STATUS_SUCCESS || pBuffer == NULL ) return TRUE;//FALSE; //obtain content from the packet ReadPacket(pPacket,pBuffer,PacketSize); result = HookFilterBuffer(pOurContext,pBuffer,PacketSize,isOutgoing); NdisFreeMemory(pBuffer,PacketSize,0); return result; } __declspec( naked ) uword wswap(uword value) { __asm { movzx eax,byte ptr [esp + 5]; mov ah ,byte ptr [esp + 4]; ret 4 } } void ReadPacket(PNDIS_PACKET Packet,PVOID pBuffer,udword dwBufSize) { PVOID virtualAddress; PNDIS_BUFFER firstBuffer, nextBuffer; ULONG totalLength; UINT len; PVOID pBuf = NULL; dword count = 0; NdisQueryPacket(Packet, NULL, NULL, &firstBuffer, NULL); while( firstBuffer != NULL) { //NdisQueryBufferSafe can't use in wdm1.0 // NdisQueryBufferSafe(firstBuffer, &virtualAddress, // &len, 16 ); NdisQueryBuffer(firstBuffer, &virtualAddress, &len); if(!virtualAddress) { // // System is running low on memory resources. // So fail the read. // break; } if( count + len > dwBufSize ) break; NdisMoveMemory(&((byte *)pBuffer)[count],virtualAddress,len); count += len; NdisGetNextBuffer(firstBuffer, &nextBuffer); firstBuffer = nextBuffer; } return; } //---- VOID HookProtocolSendPackets( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE MiniportAdapterContext, IN PPNDIS_PACKET PacketArray, IN UINT NumberOfPackets ) { udword x; PPNDIS_PACKET FilterPacketArray; UINT NumberOfFilterPackets; if( pOurContext ) { if( NumberOfPackets == 0 ) { ((SEND_PACKETS_HANDLER)pOurContext->m_pOriginalProc)( MiniportAdapterContext, PacketArray, NumberOfPackets); return; } FilterPacketArray = ExAllocatePoolWithTag(NonPagedPool,sizeof(PNDIS_PACKET) * NumberOfPackets,'HFPA'); if( FilterPacketArray == NULL ) { ((SEND_PACKETS_HANDLER)pOurContext->m_pOriginalProc)( MiniportAdapterContext, PacketArray, NumberOfPackets); return; } for(NumberOfFilterPackets = 0,x = 0; x < NumberOfPackets; x++ ) { if( HookFilterPacket(pOurContext,PacketArray[x],TRUE) ) { FilterPacketArray[NumberOfFilterPackets++] = PacketArray[x]; } } if( NumberOfFilterPackets ) { ((SEND_PACKETS_HANDLER)pOurContext->m_pOriginalProc)( MiniportAdapterContext, FilterPacketArray, NumberOfFilterPackets); } ExFreePool(FilterPacketArray); } return; } NDIS_STATUS HookProtocolWanSend( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE MacBindingHandle, IN NDIS_HANDLE LinkHandle, IN PVOID Packet ) { if( pOurContext ) { return ((WAN_SEND_HANDLER)pOurContext->m_pOriginalProc)( MacBindingHandle, LinkHandle, Packet); } return NDIS_STATUS_SUCCESS; } NDIS_STATUS HookProtocolSend( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE MacBindingHandle, IN PNDIS_PACKET Packet ) { // udword PacketSize; NTSTATUS status = NDIS_STATUS_SUCCESS; if( pOurContext ) { if( HookFilterPacket(pOurContext,Packet,TRUE) ) { status = ((SEND_HANDLER)pOurContext->m_pOriginalProc)( MacBindingHandle, Packet); } else status = NDIS_STATUS_NOT_ACCEPTED; } return status; } INT HookProtocolReceivePacket( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet ) { NTSTATUS status = NDIS_STATUS_SUCCESS; if( pOurContext ) { CheckSendHandle(pOurContext); if( HookFilterPacket(pOurContext,Packet,FALSE) ) { status = ((RECEIVE_PACKET_HANDLER)pOurContext->m_pOriginalProc)( ProtocolBindingContext, Packet); } else status = NDIS_STATUS_NOT_ACCEPTED; } return status; } NDIS_STATUS HookWanReceive( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE NdisLinkHandle, IN PUCHAR Packet, IN ULONG PacketSize ) { if( pOurContext ) { return ((WAN_RECEIVE_HANDLER)pOurContext->m_pOriginalProc)( NdisLinkHandle, Packet, PacketSize); } return NDIS_STATUS_SUCCESS; } NDIS_STATUS HookProtocolReceive( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookAheadBufferSize, IN UINT PacketSize ) { NTSTATUS status = NDIS_STATUS_SUCCESS; if( pOurContext ) { CheckSendHandle(pOurContext); // TotalReceiveBytes += PacketSize; if( pOurContext->m_pBindAdaptHandle ) { udword len = 0; if( PacketSize > LookAheadBufferSize ) { NdisTransferData(&status,pOurContext->m_pBindAdaptHandle,MacReceiveContext,0,PacketSize,m_ourPacketHandle,&len); } else { NdisMoveMemory(m_ourBuffer,LookAheadBuffer,PacketSize); } if( status == NDIS_STATUS_SUCCESS ) { TotalTransferPackets++; if( !HookFilterReceivePacket(pOurContext,PacketSize,HeaderBuffer,HeaderBufferSize,m_ourPacketHandle,FALSE) ) //if( !HookFilterPacket(pOurContext,m_ourPacketHandle,FALSE) ) return NDIS_STATUS_NOT_ACCEPTED; } else if( status == NDIS_STATUS_PENDING ) //Warning: Here An Error will be occured. TotalTransferPendingPackets++; else TotalTransferErrorPackets++; } else { TotalUnbindTransferPackets++; } status = ((RECEIVE_HANDLER)pOurContext->m_pOriginalProc)( ProtocolBindingContext, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); } return status; } VOID HookBindAdapterHandler( IN HOOK_CONTEXT_STRUCT *pOurContext, OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2) { if( pOurContext ) { ((BIND_HANDLER)pOurContext->m_pOriginalProc)(Status,BindContext, DeviceName, SystemSpecific1, SystemSpecific2); HookFuncBlock(pOurContext->m_pProtocolContent); TotalTransferErrorPackets++; } return; } VOID HookSendComplete( IN HOOK_CONTEXT_STRUCT *pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status ) { __asm int 3; ((SEND_COMPLETE_HANDLER)pOurContext->m_pOriginalProc)( ProtocolBindingContext, Packet, Status ); return; }