Изменение пакета

Home Forums Discussions Support Изменение пакета

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #9597
    Some_name
    Participant

      Здравствуйте, проблема такова, я с помощью примера PassThru пытаюсь перехватить пакет, передаваемый через определенный порт, и изменить его содержимое, то есть перевожу из hex в удобочитаемый вид, меняю данные, обратно в hex.
      Затем подменяю данные.

      Console.WriteLine(“Было” + HexToStr(((INTERMEDIATE_BUFFER)Marshal.PtrToStructure(request.EthPacket.Buffer, typeof(INTERMEDIATE_BUFFER))).m_IBuffer));
      Marshal.StructureToPtr(buffer, request.EthPacket.Buffer, true);
      string l = HexToStr(((INTERMEDIATE_BUFFER)Marshal.PtrToStructure(request.EthPacket.Buffer, typeof(INTERMEDIATE_BUFFER))).m_IBuffer);
      Console.WriteLine(“Изменено” + l);

      Ndisapi.SendPacketToAdapter(driverPtr, ref request);

      По итогу пакет так и не доходит, судя по всему отбрасывается, сниффер показывает большое количество пакетов TCP Spurious Retransmission и TCP DUP ACK.
      Есть какие-то варианты как это исправить? Насколько я понимаю пакет приходит, обрабатывается и только после команды
      Ndisapi.SendPacketToAdapter(driverPtr, ref request);
      отправляется дальше. Может я что-то неверно понимаю, и после этой команды он отправляется повторно к уже существующему?

      #9598
      Vadim Smirnov
      Keymaster

        Если пакет был изменен, то надо по меньше мере пересчитать контрольные суммы. Это делается? Если нет, то пакет с неверной контрольной суммой может быть просто отброшен стеком на принимающей стороне.

        #9599
        Some_name
        Participant

          Вы не могли бы подсказать как изменить контрольную сумму или в каком из примеров посмотреть (C#)?

          #9600
          Vadim Smirnov
          Keymaster

            Примера для C#, к сожалению нет, в следующих версиях соответствующие функции будут добавлены к ndisapi.dll, но ничего не мешает сделать сейчас:

            //
            // Function recalculates IP checksum
            //
            void
            CNdisApi::RecalculateIPChecksum(
            	PINTERMEDIATE_BUFFER pPacket
            )
            {
            	unsigned short word16;
            	unsigned int sum = 0;
            	unsigned int i = 0;
            	PUCHAR buff;
            
            	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
            
            	// Initialize checksum to zero
            	pIpHeader->ip_sum = 0;
            	buff = (PUCHAR)pIpHeader;
            
            	// Calculate IP header checksum
            	for (i = 0; i < pIpHeader->ip_hl * sizeof(DWORD); i = i + 2)
            	{
            		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
            		sum = sum + word16;
            	}
            
            	// keep only the last 16 bits of the 32 bit calculated sum and add the carries
            	while (sum >> 16)
            		sum = (sum & 0xFFFF) + (sum >> 16);
            
            	// Take the one's complement of sum
            	sum = ~sum;
            
            	pIpHeader->ip_sum = htons((unsigned short)sum);
            }
            
            //
            // Function recalculates ICMP checksum
            //
            void
            CNdisApi::RecalculateICMPChecksum(
            	PINTERMEDIATE_BUFFER pPacket
            )
            {
            	unsigned short word16, padd = 0;
            	unsigned int i, sum = 0;
            	PUCHAR buff;
            	DWORD dwIcmpLen;
            	icmphdr_ptr pIcmpHeader = NULL;
            	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
            
            	// Sanity check
            	if (pIpHeader->ip_p == IPPROTO_ICMP)
            	{
            		pIcmpHeader = (icmphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
            	}
            	else
            		return;
            
            	dwIcmpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl * 4;
            
            	if ((dwIcmpLen / 2) * 2 != dwIcmpLen)
            	{
            		padd = 1;
            		pPacket->m_IBuffer[dwIcmpLen + pIpHeader->ip_hl * 4 + sizeof(ether_header)] = 0;
            	}
            
            	buff = (PUCHAR)pIcmpHeader;
            	pIcmpHeader->checksum = 0;
            
            	// make 16 bit words out of every two adjacent 8 bit words and 
            	// calculate the sum of all 16 bit words
            	for (i = 0; i< dwIcmpLen + padd; i = i + 2) {
            		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
            		sum = sum + (unsigned long)word16;
            	}
            
            	// keep only the last 16 bits of the 32 bit calculated sum and add the carries
            	while (sum >> 16)
            		sum = (sum & 0xFFFF) + (sum >> 16);
            
            	// Take the one's complement of sum
            	sum = ~sum;
            
            	pIcmpHeader->checksum = ntohs((unsigned short)sum);
            }
            
            //
            // Function recalculates TCP checksum
            //
            void
            CNdisApi::RecalculateTCPChecksum(
            	PINTERMEDIATE_BUFFER pPacket
            )
            {
            	tcphdr_ptr pTcpHeader = NULL;
            	unsigned short word16, padd = 0;
            	unsigned int i, sum = 0;
            	PUCHAR buff;
            	DWORD dwTcpLen;
            
            	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
            
            	// Sanity check
            	if (pIpHeader->ip_p == IPPROTO_TCP)
            	{
            		pTcpHeader = (tcphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
            	}
            	else
            		return;
            
            	dwTcpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl * 4;//pPacket->m_Length - ((PUCHAR)(pTcpHeader) - pPacket->m_IBuffer);
            
            	if ((dwTcpLen / 2) * 2 != dwTcpLen)
            	{
            		padd = 1;
            		pPacket->m_IBuffer[dwTcpLen + pIpHeader->ip_hl * 4 + sizeof(ether_header)] = 0;
            	}
            
            	buff = (PUCHAR)pTcpHeader;
            	pTcpHeader->th_sum = 0;
            
            	// make 16 bit words out of every two adjacent 8 bit words and 
            	// calculate the sum of all 16 vit words
            	for (i = 0; i< dwTcpLen + padd; i = i + 2) {
            		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
            		sum = sum + (unsigned long)word16;
            	}
            
            	// add the TCP pseudo header which contains:
            	// the IP source and destination addresses,
            
            	sum = sum + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w2);
            	sum = sum + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w2);
            
            	// the protocol number and the length of the TCP packet
            	sum = sum + IPPROTO_TCP + (unsigned short)dwTcpLen;
            
            	// keep only the last 16 bits of the 32 bit calculated sum and add the carries
            	while (sum >> 16)
            		sum = (sum & 0xFFFF) + (sum >> 16);
            
            	// Take the one's complement of sum
            	sum = ~sum;
            
            	pTcpHeader->th_sum = htons((unsigned short)sum);
            }
            
            //
            // Function recalculates UDP checksum
            //
            void
            CNdisApi::RecalculateUDPChecksum(
            	PINTERMEDIATE_BUFFER pPacket
            )
            {
            	udphdr_ptr pUdpHeader = NULL;
            	unsigned short word16, padd = 0;
            	unsigned int i, sum = 0;
            	PUCHAR buff;
            	DWORD dwUdpLen;
            
            	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
            
            	// Sanity check
            	if (pIpHeader->ip_p == IPPROTO_UDP)
            	{
            		pUdpHeader = (udphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
            	}
            	else
            		return;
            
            	dwUdpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl * 4;//pPacket->m_Length - ((PUCHAR)(pTcpHeader) - pPacket->m_IBuffer);
            
            	if ((dwUdpLen / 2) * 2 != dwUdpLen)
            	{
            		padd = 1;
            		pPacket->m_IBuffer[dwUdpLen + pIpHeader->ip_hl * 4 + sizeof(ether_header)] = 0;
            	}
            
            	buff = (PUCHAR)pUdpHeader;
            	pUdpHeader->th_sum = 0;
            
            	// make 16 bit words out of every two adjacent 8 bit words and 
            	// calculate the sum of all 16 vit words
            	for (i = 0; i< dwUdpLen + padd; i = i + 2) {
            		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
            		sum = sum + (unsigned long)word16;
            	}
            
            	// add the UDP pseudo header which contains:
            	// the IP source and destination addresses,
            
            	sum = sum + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w2);
            	sum = sum + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w2);
            
            	// the protocol number and the length of the UDP packet
            	sum = sum + IPPROTO_UDP + (unsigned short)dwUdpLen;
            
            	// keep only the last 16 bits of the 32 bit calculated sum and add the carries
            	while (sum >> 16)
            		sum = (sum & 0xFFFF) + (sum >> 16);
            
            	// Take the one's complement of sum
            	sum = ~sum;
            
            	pUdpHeader->th_sum = ntohs((unsigned short)sum);
            }
            
          Viewing 4 posts - 1 through 4 (of 4 total)
          • You must be logged in to reply to this topic.