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