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

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

This topic contains 3 replies, has 2 voices, and was last updated by  Vadim Smirnov 3 months, 2 weeks ago.

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
    Moderator

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

    #9599

    Some_name
    Participant

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

    #9600

    Vadim Smirnov
    Moderator

    Примера для 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.