NDISLWF how to modify the packet

http://www.osronline.com/showThread.cfm?link=172579

You are not generally permitted to modify something that your driver doesnot 'own'. A NBL indicated to your driver is usually treated as'read-only'. To 'modify' the packet, your driver typically would copy theNBL, modify the copy, indicate the copy, and when the copy is returned, free it and return the original (unmodified) NBL to the entity that indicated it to you.


本来只想简单的block stream,因为对ndislwf不熟悉,不想把驱动写得太复杂,但朋友玩QQ里的彩虹砖块197分,自认为没有那么厉害,于是抓包一看,如果修改了包信息能否骗过游戏,提高我的成绩呢?

1.抓包信息如下:



2.我要做的就是找到这个stream,然后修改其中的内容。我用了AC算法进行数据包的扫描,当找到对应的NBL后,我写了一个函数,进行NBL的拷贝,函数如下:

PNET_BUFFER_LIST FltCopyNetBufferList(
        IN PMS_FILTER				pFilter,
	IN PNET_BUFFER_LIST			pNBL
	)
{
	BOOLEAN             bFalse = FALSE;
	PMDL				pMdl,pnextMdl,pnewMdl;
	PMDL				pFirstMDL =	NULL;
	PUCHAR				pMDLAddress = NULL;
	PNET_BUFFER_LIST	pNetBufferList = NULL;
	PNET_BUFFER			pCurrentNetBuffer = NULL;
	LONG				dataLength = 0;
	LONG				TotalLength = 0;
	PUCHAR				pAddress;
	LONG				lOffset;
	//LONG				NBDL;
	//LONG				NBDO;
	
	DEBUGP(DL_TEST,("==============>CopyNetBufferList\n"));  

	pnextMdl = NULL;

	pCurrentNetBuffer =  NET_BUFFER_LIST_FIRST_NB(pNBL);
//	for(pCurrentNetBuffer =  NET_BUFFER_LIST_FIRST_NB(pNBL);
//		pCurrentNetBuffer != NULL;
//		pCurrentNetBuffer =  NET_BUFFER_NEXT_NB(pCurrentNetBuffer)
//		)
//	{
		pMdl = NET_BUFFER_CURRENT_MDL(pCurrentNetBuffer);
		lOffset = NET_BUFFER_CURRENT_MDL_OFFSET(pCurrentNetBuffer);
		//NBDL = NET_BUFFER_DATA_LENGTH(pCurrentNetBuffer);
		//NBDO = NET_BUFFER_DATA_OFFSET(pCurrentNetBuffer);
		do{
			NdisQueryMdl(pMdl, &pAddress, &dataLength, NormalPagePriority);
			dataLength -= lOffset;
			pMDLAddress = (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle, dataLength, FILTER_ALLOC_TAG, LowPoolPriority);   
			if(NULL == pMDLAddress)
			{
				return NULL;
			}
			NdisZeroMemory(pMDLAddress, dataLength);  

			//add a discreption for the allocate memory
			pFirstMDL = NdisAllocateMdl(pFilter->FilterHandle, pMDLAddress, dataLength);
			pFirstMDL->Next = NULL;
			if(pFirstMDL == NULL)	
			{	
				DEBUGP(DL_TEST,("PMDL Fail....\n"));
				break;
			}  

			pNetBufferList = NdisAllocateNetBufferAndNetBufferList(  
				pFilter->SNBLPool,
				0,//sizeof(FILTER_SEND_NETBUFLIST_RSVD), Request control offset delta	
				0,			 // back fill size	 
				pFirstMDL,	
				0,			// Data offset	 
				dataLength);   
			if(pNetBufferList == NULL)	
			{	
				NdisFreeMdl(pFirstMDL); 
				break;	
			}
			//change the checksum
			//NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO
			NET_BUFFER_LIST_INFO(pNetBufferList, TcpIpChecksumNetBufferListInfo) = NET_BUFFER_LIST_INFO(pNBL, TcpIpChecksumNetBufferListInfo);			
			pNetBufferList->SourceHandle = pFilter->FilterHandle;
			TotalLength += dataLength;
			NdisMoveMemory((pMDLAddress + 0),(pAddress + lOffset), dataLength);//the first mdl OK
			//the following MDL , and the next MDL, they offet is 0!
			pMdl = pMdl->Next;
			pnextMdl = pFirstMDL;
			while(NULL != pMdl){
				NdisQueryMdl(pMdl, &pAddress, &dataLength, NormalPagePriority);
				pMDLAddress = (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle, dataLength, FILTER_ALLOC_TAG, LowPoolPriority);   
				if(NULL == pMDLAddress)
				{
					return NULL;
				}
				NdisZeroMemory(pMDLAddress, dataLength);  

				//add a discreption for the allocate memory
				pnewMdl = NdisAllocateMdl(pFilter->FilterHandle, pMDLAddress, dataLength);
				if(pnewMdl == NULL)	
				{	
					DEBUGP(DL_TEST,("NEWMDL Fail....\n"));
					break;
				} 
				TotalLength += dataLength;
				NdisMoveMemory(pMDLAddress, pAddress, dataLength);
				*(pMDLAddress+dataLength-1) = 'T';
				pMdl = pMdl->Next;
				pnextMdl->Next = pnewMdl;
				pnextMdl = pnewMdl;
				pnextMdl->Next = NULL;
			} 	
		}while(bFalse);
		//AFFTER COPY THE MDL, THEN WE SHOULD MODIFY THE NET_BUFFER
		NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pNetBufferList)) = TotalLength;
		NET_BUFFER_LIST_NEXT_NBL(pNetBufferList) = NULL;
//	}
	DEBUGP(DL_TEST,("<==============CopyNetBufferList\n")); 	
	return pNetBufferList;
}
在这个函数中,我把只是简单把COPY的数据最后一个字节改为了'T'。


3.修改后,捕包截图如下:



3.针对修改score我修改了上面的函数,成绩可以改为200,不过服务器那边很可能用key做了验证,因为改为200后,返回数据包如下:



4.与前面block stream类似,将original NBL block掉,将copied NBL通过NdisFSendNetBufferLists传给底层。在FilterSendNetBufferListsComplete中:

if( NdisGetPoolFromNetBufferList(NetBufferLists) == pFilter->SNBLPool ){
		NdisFreeNetBufferList(NetBufferLists);
	} else {		
		NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, SendCompleteFlags);
	}
进行相应NBL的释放。

5.对于NDISLWF,我并不熟悉,所以在上面的copy函数中,如果一个NBL中存在多个NB该如何处理呢?也许需要动态分配NB,然后将它们链接起来。


在写修改包内容的示例过程中,很难在网上找到相关信息,我参考了如下几个网站:

http://blog.donews.com/uuty/archive/2011/03/24/1473377.aspx

http://yexin218.iteye.com/blog/648533

NDIS 6 Net Buffer Lists and Net Buffers

http://www.codemachine.com/article_ndis6nbls.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值