【转帖】 NDIS Hook的框架代码

来源:互联网 发布:mac安装win10怎么分区 编辑:程序博客网 时间:2024/05/17 01:35
//
//Protocol Wrapper Version 1.05
//Author: gjp
//email: gjpland@netease.com
//


#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_CHARACTERISTICSNdis40Chars;
#else
NDIS40_PROTOCOL_CHARACTERISTICS;
#endif

//
// Start of NDIS 4.1 extensions.
//

CO_SEND_COMPLETE_HANDLERCoSendCompleteHandler;
CO_STATUS_HANDLERCoStatusHandler;
CO_RECEIVE_PACKET_HANDLERCoReceivePacketHandler;
CO_REQUEST_HANDLERCoRequestHandler;
CO_REQUEST_COMPLETE_HANDLERCoRequestCompleteHandler;

} 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 0x140x08
// NDIS 4.XX 0x60 0x140x00
// NDIS 4.01 0x8C 0x140x00
// NDIS 5.XX 0x10 0x140x00


//-----
VOID HookProtocolSendPackets(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLEMiniportAdapterContext,
IN PPNDIS_PACKETPacketArray,
IN UINTNumberOfPackets
);

NDIS_STATUS HookProtocolWanSend(
IN HOOK_CONTEXT_STRUCT *pOurContext,
INNDIS_HANDLEMacBindingHandle,
INNDIS_HANDLELinkHandle,
INPVOIDPacket
);
NDIS_STATUS HookProtocolSend(
IN HOOK_CONTEXT_STRUCT *pOurContext,
INNDIS_HANDLEMacBindingHandle,
INPNDIS_PACKETPacket
);

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,
INNDIS_HANDLENdisLinkHandle,
INPUCHARPacket,
INULONGPacketSize
);
INTHookProtocolReceivePacket(
IN HOOK_CONTEXT_STRUCT *pOurContext,
INNDIS_HANDLEProtocolBindingContext,
INPNDIS_PACKETPacket
);

VOID HookBindAdapterHandler(
IN HOOK_CONTEXT_STRUCT *pOurContext,
OUT PNDIS_STATUSStatus,
IN NDIS_HANDLEBindContext,
IN PNDIS_STRINGDeviceName,
IN PVOIDSystemSpecific1,
IN PVOIDSystemSpecific2);

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_BLOCKMacHandle;// pointer to our MAC
NDIS_HANDLEMacBindingHandle;// context when calling MacXX funcs
PNDIS_ADAPTER_BLOCKAdapterHandle;// pointer to our adapter
PNDIS_PROTOCOL_BLOCKProtocolHandle;// pointer to our protocol
NDIS_HANDLEProtocolBindingContext;// context when calling ProtXX funcs
PNDIS_OPEN_BLOCKAdapterNextOpen;// used by adapter's OpenQueue
PNDIS_OPEN_BLOCKProtocolNextOpen;// used by protocol's OpenQueue
PFILE_OBJECTFileObject;// created by operating system
BOOLEANClosing;// TRUE when removing this struct
BOOLEANUnloading;// TRUE when processing unload
NDIS_HANDLECloseRequestHandle;// 0 indicates an internal close
KSPIN_LOCKSpinLock;// guards Closing
PNDIS_OPEN_BLOCKNextGlobalOpen;

//
// These are optimizations for getting to MAC routines.They are not
// necessary, but are here to save a dereference through the MAC block.
//

SEND_HANDLERSendHandler;
TRANSFER_DATA_HANDLERTransferDataHandler;

//
// 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_HANDLERSendCompleteHandler;
TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;
RECEIVE_HANDLERReceiveHandler;
RECEIVE_COMPLETE_HANDLERReceiveCompleteHandler;

//
// Extentions to the OPEN_BLOCK since Product 1.
//
RECEIVE_HANDLERPostNt31ReceiveHandler;
RECEIVE_COMPLETE_HANDLERPostNt31ReceiveCompleteHandler;

//
// NDIS 4.0 extensions
//
RECEIVE_PACKET_HANDLERReceivePacketHandler;
SEND_PACKETS_HANDLERSendPacketsHandler;

//
// Needed for PnP
//
UNICODE_STRINGAdapterName;// 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;
UINTlen;
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_HANDLEMiniportAdapterContext,
IN PPNDIS_PACKETPacketArray,
IN UINTNumberOfPackets
)
{
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,
INNDIS_HANDLEMacBindingHandle,
INNDIS_HANDLELinkHandle,
INPVOIDPacket
)
{
if( pOurContext )
{
return ((WAN_SEND_HANDLER)pOurContext->m_pOriginalProc)(
MacBindingHandle,
LinkHandle,
Packet);
}
return NDIS_STATUS_SUCCESS;
}

NDIS_STATUS HookProtocolSend(
IN HOOK_CONTEXT_STRUCT *pOurContext,
INNDIS_HANDLEMacBindingHandle,
INPNDIS_PACKETPacket
)
{
//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;
}

INTHookProtocolReceivePacket(
IN HOOK_CONTEXT_STRUCT *pOurContext,
INNDIS_HANDLEProtocolBindingContext,
INPNDIS_PACKETPacket
)
{
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,
INNDIS_HANDLENdisLinkHandle,
INPUCHARPacket,
INULONGPacketSize
)
{

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_STATUSStatus,
IN NDIS_HANDLEBindContext,
IN PNDIS_STRINGDeviceName,
IN PVOIDSystemSpecific1,
IN PVOIDSystemSpecific2)
{

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;
}
原创粉丝点击