阅读:1873回复:2
修改prassthru实现网络数据包的修改出现蓝屏,请高手救命!
如题,代码如下:
请高手指教: NDIS_STATUS MPSend( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet, IN UINT Flags ) { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; NDIS_STATUS Status; PNDIS_PACKET MyPacket; PVOID MediaSpecificInfo = NULL; ULONG MediaSpecificInfoSize = 0; #ifdef NDIS51 { PNDIS_PACKET_STACK pStack; BOOLEAN Remaining; pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining); if (Remaining) { ASSERT(pStack); NdisSend(&Status, pAdapt->BindingHandle, Packet); return(Status); } } #endif // NDIS51 NdisAllocatePacket(&Status, &MyPacket,pAdapt->SendPacketPoolHandle); if (Status == NDIS_STATUS_SUCCESS) { PSEND_RSVD SendRsvd; //添加的代码用于修改数据包 BOOLEAN bPass = TRUE; UCHAR buffer[MAX_PACKET_LEN]; ULONG nReadBytes; PIPHeader pIPHeader; PNDIS_BUFFER MyBuffer; PUCHAR pPacketContent; USHORT iphdrlen; // 读取封包中的数据,这里仅读取封包头即可 FltReadPacketData(Packet, buffer, MAX_PACKET_LEN, &nReadBytes); // 检查过滤规则,看看是否允许这个封包进行修改 bPass = FltCheckFilterRules(buffer, nReadBytes, TRUE); if (!bPass) { pIPHeader = (PIPHeader)(buffer+14); iphdrlen = (pIPHeader->iphVerLen & 0x0f) * sizeof(ULONG); //point to IP Packet header //修改dscp字段 我主要用改程序来修改dscp字段,所以修改的部分就在这里了 pIPHeader->ipTOS=0x12; pIPHeader->ipChecksum=0x00; // 计算ip首部校验和 pIPHeader->ipChecksum = checksum((USHORT *)pIPHeader,iphdrlen); //=========================================================================== //把数据copy给mybuffer NdisAllocateBuffer(&Status,&MyBuffer,pAdapt->SendPacketPoolHandle,buffer,nReadBytes); NdisChainBufferAtFront(MyPacket, MyBuffer); //把MyBuffer关联到MyPacket SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved); SendRsvd->OriginalPkt = MyPacket; MyPacket->Private.Head->Next = NULL; MyPacket->Private.Tail = NULL; NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK); NdisReturnPackets(&Packet, 1); NdisSend(&Status,pAdapt->BindingHandle,MyPacket); pPacketContent=buffer; if(Status != NDIS_STATUS_PENDING) { NdisUnchainBufferAtFront(MyPacket ,&MyBuffer); //从MyPacket中解除buffer NdisQueryBufferSafe(MyBuffer,&pPacketContent, &nReadBytes,NormalPagePriority ); if(buffer != NULL) NdisFreeMemory(buffer,nReadBytes, 0); NdisFreeBuffer(MyBuffer); } } else { SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved); SendRsvd->OriginalPkt = Packet; MyPacket->Private.Flags = Flags; MyPacket->Private.Head = Packet->Private.Head; MyPacket->Private.Tail = Packet->Private.Tail; #ifdef WIN9X MyPacket->Private.ValidCounts = FALSE; #endif NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket), NDIS_OOB_DATA_FROM_PACKET(Packet), sizeof(NDIS_PACKET_OOB_DATA)); #ifndef WIN9X NdisIMCopySendPerPacketInfo(MyPacket, Packet); #endif NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet, &MediaSpecificInfo, &MediaSpecificInfoSize); if (MediaSpecificInfo || MediaSpecificInfoSize) { NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket, MediaSpecificInfo, MediaSpecificInfoSize); } NdisSend(&Status, pAdapt->BindingHandle, MyPacket); if (Status != NDIS_STATUS_PENDING) { #ifndef WIN9X NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket); #endif NdisFreePacket(MyPacket); } } } else { } return(Status); } |
|
沙发#
发布于:2008-09-18 10:58
下面是上面要用到的函数的定义,其中FltCheckFilterRules函数实现的只是检查改数据包是不是ip包,如果是ip包我们就对其进行数据修改
//计算校验和 USHORT checksum(USHORT* buff, int size) { unsigned long cksum = 0; while(size>1) { cksum += *buff++; size -= sizeof(USHORT); } // 是奇数 if(size) { cksum += *(UCHAR*)buff; } // 将32位的chsum高16位和低16位相加,然后取反 cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (USHORT)(~cksum); } // 读取封包中的数据 void FltReadPacketData(PNDIS_PACKET pPacket, PUCHAR lpBufferIn, ULONG nNumberToRead, PUINT lpNumberOfRead) { PUCHAR pBuf; ULONG nBufferSize; PNDIS_BUFFER pBufferDes = NULL; // 检查参数 if(pPacket == NULL || lpBufferIn == NULL || nNumberToRead == 0) { if(lpNumberOfRead != NULL) { *lpNumberOfRead = 0; return ; } } // 设置返回数据 *lpNumberOfRead = 0; // 遍历封包中的缓冲区描述表,将数据复制到用户缓冲区 pBufferDes = pPacket->Private.Head; while(pBufferDes != pPacket->Private.Tail && pBufferDes != NULL) { // 获取此缓冲区描述表的缓冲区信息 NdisQueryBufferSafe(pBufferDes, &pBuf, &nBufferSize, NormalPagePriority); if(pBuf == NULL) return; if(nNumberToRead > nBufferSize) // 复制整个缓冲区 { NdisMoveMemory(lpBufferIn + *lpNumberOfRead, pBuf, nBufferSize); nNumberToRead -= nBufferSize; *lpNumberOfRead += nBufferSize; } else // 仅复制剩下的部分 { NdisMoveMemory(lpBufferIn + *lpNumberOfRead, pBuf, nNumberToRead); *lpNumberOfRead += nNumberToRead; return; } // 下一个缓冲区描述表 pBufferDes = pBufferDes->Next; } } // 检查过滤规则 BOOLEAN FltCheckFilterRules(PUCHAR pPacketData, ULONG nDataLen, BOOLEAN bIncludeETHdr) { int nLeavingLen = nDataLen; PETHeader pEtherHdr; PIPHeader pIpHdr; PTCPHeader pTcpHdr; PUDPHeader pUdpHdr; // 从缓冲区中萃取出IP头 // 如果包含以太头,就要先检查以太头 if(bIncludeETHdr) { if(nLeavingLen < sizeof(ETHeader)) { return TRUE; } nLeavingLen -= sizeof(ETHeader); pEtherHdr = (PETHeader)pPacketData; if(pEtherHdr->type != 0x8) // 如果不是IP协议,则不处理 return TRUE; pIpHdr = (PIPHeader)(pEtherHdr + 1); } else { pIpHdr = (PIPHeader)pPacketData; } // 验证剩余数据长度,防止发生内核非法访问 if(nLeavingLen < sizeof(IPHeader)) return TRUE; nLeavingLen -= sizeof(IPHeader); // 检查版本信息,我们仅处理IPv4 if(((pIpHdr->iphVerLen >> 4) & 0x0f) == 6) { return TRUE; } // 默认情况下接收所有封包 return FALSE; } |
|
板凳#
发布于:2008-09-18 11:01
这个程序编译通过后,我将它安装以后,一开机就出现蓝屏,我调了很久了 ,实在是调不出来了,请高手指点指点,老板催得慌,我饭碗不保啊,救命啊!
|
|