Home › Forums › Discussions › Support › Изменение пакета
- This topic has 3 replies, 2 voices, and was last updated 7 years, 5 months ago by Vadim Smirnov.
-
AuthorPosts
-
June 4, 2017 at 9:33 am #9597
Здравствуйте, проблема такова, я с помощью примера 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);
отправляется дальше. Может я что-то неверно понимаю, и после этой команды он отправляется повторно к уже существующему?June 6, 2017 at 10:14 am #9598Если пакет был изменен, то надо по меньше мере пересчитать контрольные суммы. Это делается? Если нет, то пакет с неверной контрольной суммой может быть просто отброшен стеком на принимающей стороне.
June 6, 2017 at 10:54 am #9599Вы не могли бы подсказать как изменить контрольную сумму или в каком из примеров посмотреть (C#)?
June 8, 2017 at 9:08 am #9600Примера для 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); }
-
AuthorPosts
- You must be logged in to reply to this topic.