Example #1
0
/*
 * Entry.
 */
int __cdecl main(int argc, char **argv)
{
    HANDLE handle, console;
    UINT i;
    INT16 priority = 0;
    unsigned char packet[MAXBUF];
    UINT packet_len;
    WINDIVERT_ADDRESS addr;
    PWINDIVERT_IPHDR ip_header;
    PWINDIVERT_IPV6HDR ipv6_header;
    PWINDIVERT_ICMPHDR icmp_header;
    PWINDIVERT_ICMPV6HDR icmpv6_header;
    PWINDIVERT_TCPHDR tcp_header;
    PWINDIVERT_UDPHDR udp_header;

    // Check arguments.
    switch (argc)
    {
        case 2:
            break;
        case 3:
            priority = (INT16)atoi(argv[2]);
            break;
        default:
            fprintf(stderr, "usage: %s windivert-filter [priority]\n",
                argv[0]);
            fprintf(stderr, "examples:\n");
            fprintf(stderr, "\t%s true\n", argv[0]);
            fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000\n",
                argv[0]);
            fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -4000\n", argv[0]);
            exit(EXIT_FAILURE);
    }

    // Get console for pretty colors.
    console = GetStdHandle(STD_OUTPUT_HANDLE);

    // Divert traffic matching the filter:
    handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority,
        WINDIVERT_FLAG_SNIFF);
    if (handle == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_INVALID_PARAMETER)
        {
            fprintf(stderr, "error: filter syntax error\n");
            exit(EXIT_FAILURE);
        }
        fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
            GetLastError());
        exit(EXIT_FAILURE);
    }

    // Max-out the packet queue:
    if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_LEN, 8192))
    {
        fprintf(stderr, "error: failed to set packet queue length (%d)\n",
            GetLastError());
        exit(EXIT_FAILURE);
    }
    if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_TIME, 2048))
    {
        fprintf(stderr, "error: failed to set packet queue time (%d)\n",
            GetLastError());
        exit(EXIT_FAILURE);
    }

    // Main loop:
    while (TRUE)
    {
        // Read a matching packet.
        if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
        {
            fprintf(stderr, "warning: failed to read packet (%d)\n",
                GetLastError());
            continue;
        }
       
        // Print info about the matching packet.
        WinDivertHelperParsePacket(packet, packet_len, &ip_header,
            &ipv6_header, &icmp_header, &icmpv6_header, &tcp_header,
            &udp_header, NULL, NULL);
        if (ip_header == NULL && ipv6_header == NULL)
        {
            fprintf(stderr, "warning: junk packet\n");
        }

        // Dump packet info: 
        putchar('\n');
        SetConsoleTextAttribute(console, FOREGROUND_RED);
        printf("Packet [Direction=%u IfIdx=%u SubIfIdx=%u]\n",
            addr.Direction, addr.IfIdx, addr.SubIfIdx);
        if (ip_header != NULL)
        {
            UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
            UINT8 *dst_addr = (UINT8 *)&ip_header->DstAddr;
            SetConsoleTextAttribute(console,
                FOREGROUND_GREEN | FOREGROUND_RED);
            printf("IPv4 [Version=%u HdrLength=%u TOS=%u Length=%u Id=0x%.4X "
                "Reserved=%u DF=%u MF=%u FragOff=%u TTL=%u Protocol=%u "
                "Checksum=0x%.4X SrcAddr=%u.%u.%u.%u DstAddr=%u.%u.%u.%u]\n",
                ip_header->Version, ip_header->HdrLength,
                ntohs(ip_header->TOS), ntohs(ip_header->Length),
                ntohs(ip_header->Id), WINDIVERT_IPHDR_GET_RESERVED(ip_header),
                WINDIVERT_IPHDR_GET_DF(ip_header),
                WINDIVERT_IPHDR_GET_MF(ip_header),
                ntohs(WINDIVERT_IPHDR_GET_FRAGOFF(ip_header)), ip_header->TTL,
                ip_header->Protocol, ntohs(ip_header->Checksum),
                src_addr[0], src_addr[1], src_addr[2], src_addr[3],
                dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
        }
        if (ipv6_header != NULL)
        {
            UINT16 *src_addr = (UINT16 *)&ipv6_header->SrcAddr;
            UINT16 *dst_addr = (UINT16 *)&ipv6_header->DstAddr;
            SetConsoleTextAttribute(console,
                FOREGROUND_GREEN | FOREGROUND_RED);
            printf("IPv6 [Version=%u TrafficClass=%u FlowLabel=%u Length=%u "
                "NextHdr=%u HopLimit=%u SrcAddr=",
                ipv6_header->Version,
                WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(ipv6_header),
                ntohl(WINDIVERT_IPV6HDR_GET_FLOWLABEL(ipv6_header)),
                ntohs(ipv6_header->Length), ipv6_header->NextHdr,
                ipv6_header->HopLimit);
            for (i = 0; i < 8; i++)
            {
                printf("%x%c", ntohs(src_addr[i]), (i == 7? ' ': ':'));
            } 
            fputs("DstAddr=", stdout);
            for (i = 0; i < 8; i++)
            {
                printf("%x", ntohs(dst_addr[i]));
                if (i != 7)
                {
                    putchar(':');
                }
            }
            fputs("]\n", stdout);
        }
        if (icmp_header != NULL)
        {
            SetConsoleTextAttribute(console, FOREGROUND_RED);
            printf("ICMP [Type=%u Code=%u Checksum=0x%.4X Body=0x%.8X]\n",
                icmp_header->Type, icmp_header->Code,
                ntohs(icmp_header->Checksum), ntohl(icmp_header->Body));
        }
        if (icmpv6_header != NULL)
        {
            SetConsoleTextAttribute(console, FOREGROUND_RED);
            printf("ICMPV6 [Type=%u Code=%u Checksum=0x%.4X Body=0x%.8X]\n",
                icmpv6_header->Type, icmpv6_header->Code,
                ntohs(icmpv6_header->Checksum), ntohl(icmpv6_header->Body));
        }
        if (tcp_header != NULL)
        {
            SetConsoleTextAttribute(console, FOREGROUND_GREEN);
            printf("TCP [SrcPort=%u DstPort=%u SeqNum=%u AckNum=%u "
                "HdrLength=%u Reserved1=%u Reserved2=%u Urg=%u Ack=%u "
                "Psh=%u Rst=%u Syn=%u Fin=%u Window=%u Checksum=0x%.4X "
                "UrgPtr=%u]\n",
                ntohs(tcp_header->SrcPort), ntohs(tcp_header->DstPort),
                ntohl(tcp_header->SeqNum), ntohl(tcp_header->AckNum),
                tcp_header->HdrLength, tcp_header->Reserved1,
                tcp_header->Reserved2, tcp_header->Urg, tcp_header->Ack,
                tcp_header->Psh, tcp_header->Rst, tcp_header->Syn,
                tcp_header->Fin, ntohs(tcp_header->Window),
                ntohs(tcp_header->Checksum), ntohs(tcp_header->UrgPtr));
        }
        if (udp_header != NULL)
        {
            SetConsoleTextAttribute(console, FOREGROUND_GREEN);
            printf("UDP [SrcPort=%u DstPort=%u Length=%u "
                "Checksum=0x%.4X]\n",
                ntohs(udp_header->SrcPort), ntohs(udp_header->DstPort),
                ntohs(udp_header->Length), ntohs(udp_header->Checksum));
        }
        SetConsoleTextAttribute(console, FOREGROUND_GREEN | FOREGROUND_BLUE);
        for (i = 0; i < packet_len; i++)
        {
            if (i % 20 == 0)
            {
                printf("\n\t");
            }
            printf("%.2X", (UINT8)packet[i]);
        }
        SetConsoleTextAttribute(console, FOREGROUND_RED | FOREGROUND_BLUE);
        for (i = 0; i < packet_len; i++)
        {
            if (i % 40 == 0)
            {
                printf("\n\t");
            }
            if (isprint(packet[i]))
            {
                putchar(packet[i]);
            }
            else
            {
                putchar('.');
            }
        }
        putchar('\n');
        SetConsoleTextAttribute(console,
            FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    }
}
Example #2
0
/* Intercepta pacotes. */
void DS_control (void *lparam)
{
  HANDLE handle = (HANDLE) lparam;
  WINDIVERT_ADDRESS addr;
  PWINDIVERT_IPHDR ip_header;
  PWINDIVERT_IPV6HDR ipv6_header;
  PWINDIVERT_ICMPHDR icmp_header;
  PWINDIVERT_ICMPV6HDR icmpv6_header;
  PWINDIVERT_TCPHDR tcp_header;
  PWINDIVERT_UDPHDR udp_header;
  UINT packet_len = 0;
	UINT payload_len = 0;
  PVOID payload = NULL;
  FILE *fp = NULL;
  unsigned char packet [1024];
  char *ptrs [256], path [256];
  
  Sleep(500);
  while (TRUE)
  {
    if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
      continue;
    
    WinDivertHelperCalcChecksums(packet, packet_len, WINDIVERT_HELPER_NO_REPLACE);
    
		WinDivertHelperParsePacket(packet, packet_len, &ip_header,
      &ipv6_header, &icmp_header, &icmpv6_header, &tcp_header,
      &udp_header, &payload, &payload_len);
    
    if (ip_header != NULL || ipv6_header != NULL || icmp_header != NULL || 
      icmpv6_header != NULL || tcp_header != NULL || udp_header != NULL)
    {
      if (stop_windivert_process == 1)
         continue;
      
      WaitForSingleObject(g_mutex, INFINITE);
      
      /* IPv4 packet. */
      if (ip_header != NULL)
      {
        for (int a=0; a<6; a++)
          if ((ptrs[a] = realloc(ptrs[a], 256)) != NULL)
            memset(ptrs[a], '\0', 256);
        
        UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
        UINT8 *dst_addr = (UINT8 *)&ip_header->DstAddr;
        sprintf(ptrs[0], "%d", (current_packet_index + 1));
        sprintf(ptrs[1], "%u.%u.%u.%u", src_addr[0], src_addr[1], src_addr[2], src_addr[3]);
        sprintf(ptrs[2], "%u.%u.%u.%u", dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
        sprintf(ptrs[4], "%d", packet_len);
        
        if (tcp_header != NULL) 
        {
          sprintf(ptrs[5], "V:%u - TTL:%u - P:%u - [ TCP ] SrcPort:%u - DstPort:%u - SeqNum:%u - AckNum:%u - Urg:%u "
            "- Ack:%u - Psh:%u - Rst:%u - Syn:%u - Fin:%u - Window:%u - UrgPtr:%u", 
              ip_header->Version, ip_header->TTL, ip_header->Protocol, ntohs(tcp_header->SrcPort), ntohs(tcp_header->DstPort), 
              ntohl(tcp_header->SeqNum), ntohl(tcp_header->AckNum), tcp_header->Urg, tcp_header->Ack, tcp_header->Psh, 
              tcp_header->Rst, tcp_header->Syn, tcp_header->Fin, ntohs(tcp_header->Window), ntohs(tcp_header->UrgPtr));
          memcpy(ptrs[3], "TCP", strlen("TCP"));
        } 
        else if (udp_header != NULL) 
        {
          sprintf(ptrs[5], "V:%u - TTL:%u - P:%u - [ UDP ] SrcPort: %u - DstPort: %u - Length: %u", 
              ip_header->Version, ip_header->TTL, ip_header->Protocol,
              ntohs(udp_header->SrcPort), ntohs(udp_header->DstPort), 
              ntohs(udp_header->Length), ntohs(udp_header->Checksum));
          memcpy(ptrs[3], "UDP", strlen("UDP"));
        } 
        else 
        {
          sprintf(ptrs[5], "V:%u - HL:%u - TOS:%u - L:%u - ID:0x%.4X - RS:%u - DF:%u - MF:%u - FO:%u - TTL:%u - P:%u", 
            ip_header->Version, ip_header->HdrLength, ntohs(ip_header->TOS), ntohs(ip_header->Length), ntohs(ip_header->Id),
            WINDIVERT_IPHDR_GET_RESERVED(ip_header), WINDIVERT_IPHDR_GET_DF(ip_header), WINDIVERT_IPHDR_GET_MF(ip_header),
            ntohs(WINDIVERT_IPHDR_GET_FRAGOFF(ip_header)), ip_header->TTL, ip_header->Protocol);
          
          if (icmp_header != NULL)
            memcpy(ptrs[3], "ICMP", strlen("ICMP"));
          if (icmpv6_header != NULL)
            memcpy(ptrs[3], "ICMPv6", strlen("ICMPv6"));
          else
            memcpy(ptrs[3], "IPv4", strlen("IPv4"));
        }
        
        insert_listview_item(
          listview, current_packet_index, ptrs[0], ptrs[1], ptrs[2], ptrs[3], ptrs[4], ptrs[5]);
        current_packet_index++;
      }
      
      /* IPv6 packet. */
      else if (ipv6_header != NULL)
      {
        for (int a=0; a<6; a++)
          if ((ptrs[a] = realloc(ptrs[a], 256)) != NULL)
            memset(ptrs[a], '\0', 256);
        
        UINT16 *src_addr = (UINT16 *)&ipv6_header->SrcAddr;
        UINT16 *dst_addr = (UINT16 *)&ipv6_header->DstAddr;
        
        sprintf(ptrs[0], "%d", (current_packet_index + 1));
        sprintf(ptrs[1], "%x:%x:%x:%x", ntohs(src_addr[0]), ntohs(src_addr[1]), ntohs(src_addr[2]), ntohs(src_addr[3]));
        sprintf(ptrs[2], "%x:%x:%x:%x", ntohs(dst_addr[0]), ntohs(dst_addr[1]), ntohs(dst_addr[2]), ntohs(dst_addr[3]));
        sprintf(ptrs[4], "%d", packet_len);
        
        if (tcp_header != NULL)
        {
          sprintf(ptrs[5], 
            "V:%u - TC:%u - FL:%u - LG:%u - NH:%u - HL:%u [ TCP ] SrcPort:%u - DstPort:%u - "
            "SeqNum:%u - AckNum:%u - Urg:%u - Ack:%u - Psh:%u - Rst:%u - Syn:%u - Fin:%u - Window:%u - UrgPtr:%u",
            ipv6_header->Version, WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(ipv6_header), 
            ntohl(WINDIVERT_IPV6HDR_GET_FLOWLABEL(ipv6_header)),
            ntohs(ipv6_header->Length), ipv6_header->NextHdr, ipv6_header->HopLimit, 
            ntohs(tcp_header->SrcPort), ntohs(tcp_header->DstPort), 
            ntohl(tcp_header->SeqNum), ntohl(tcp_header->AckNum), tcp_header->Urg, tcp_header->Ack, tcp_header->Psh, 
            tcp_header->Rst, tcp_header->Syn, tcp_header->Fin, ntohs(tcp_header->Window), ntohs(tcp_header->UrgPtr));
          memcpy(ptrs[3], "IPv6 + TCP", strlen("IPv6 + TCP"));
        } 
        else if (udp_header != NULL) 
        {
          sprintf(ptrs[5], 
            "V:%u - TC:%u - FL:%u - LG:%u - NH:%u - HL:%u [ UDP ] - DstPort: %u - Length: %u",
            ipv6_header->Version, WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(ipv6_header), 
            ntohl(WINDIVERT_IPV6HDR_GET_FLOWLABEL(ipv6_header)),
            ntohs(ipv6_header->Length), ipv6_header->NextHdr, ipv6_header->HopLimit,
            ntohs(udp_header->SrcPort), ntohs(udp_header->DstPort), 
            ntohs(udp_header->Length), ntohs(udp_header->Checksum));
          memcpy(ptrs[3], "IPv6 + UDP", strlen("IPv6 + UDP"));
        } 
        else 
        {
          sprintf(ptrs[5], "V:%u - TC:%u - FL:%u - LG:%u - NH:%u - HL:%u",
            ipv6_header->Version, WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(ipv6_header), 
            ntohl(WINDIVERT_IPV6HDR_GET_FLOWLABEL(ipv6_header)),
            ntohs(ipv6_header->Length), ipv6_header->NextHdr, ipv6_header->HopLimit);
          
          if (icmp_header != NULL)
            memcpy(ptrs[3], "ICMP", strlen("ICMP"));
          if (icmpv6_header != NULL)
            memcpy(ptrs[3], "ICMPv6", strlen("ICMPv6"));
          else
            memcpy(ptrs[3], "IPv6", strlen("IPv6"));
        }
        
        insert_listview_item(
          listview, current_packet_index, ptrs[0], ptrs[1], ptrs[2], ptrs[3], ptrs[4], ptrs[5]);
        current_packet_index++;
      }
      
      /* Pacote desconhecido. */
      else {
       insert_listview_item(listview, current_packet_index, "Unknown packet", "", "", "", "", "");
       current_packet_index++;
      }
      
      /* > Salva dados do pacote em arquivo de log. */
      memset(path, '\0', 256);
      sprintf(path, "log\\%d.log", (current_packet_index - 1));
      
      if ((fp = fopen(path, "w")) != NULL)
      {        
        fprintf(fp, "Item: %d\r\nDirection: %u\r\nInterface index: %u\r\n"
          "Sub-interface index: %u\r\n\r\n",
            current_packet_index, addr.Direction, addr.IfIdx, addr.SubIfIdx);
        
        /* IPv4 packet. */
        if (ip_header != NULL)
        {
          UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
          UINT8 *dst_addr = (UINT8 *)&ip_header->DstAddr;
        
          fprintf(fp, 
            "Protocol: IP (Internet Protocol)\r\n"
            "Version: %u\r\nHeader length: %u\r\nTOS (type of service): %u\r\n"
            "Total length: %u\r\nIdentification: 0x%.4X\r\n", 
              ip_header->Version, ip_header->HdrLength, ntohs(ip_header->TOS), 
              ntohs(ip_header->Length), ntohs(ip_header->Id));
          
          fprintf(fp, 
            "Reserved: %u\r\n"
            "DF: %u\r\nMF: %u\r\nFragOff: %u\r\nTTL: %u\r\nProtocol: %u\r\nChecksum: 0x%.4X\r\n"
            "Source address: %u.%u.%u.%u\r\nDestination address: %u.%u.%u.%u\r\n\r\n", 
              WINDIVERT_IPHDR_GET_RESERVED(ip_header), WINDIVERT_IPHDR_GET_DF(ip_header),
              WINDIVERT_IPHDR_GET_MF(ip_header), ntohs(WINDIVERT_IPHDR_GET_FRAGOFF(ip_header)), 
              ip_header->TTL, ip_header->Protocol, ntohs(ip_header->Checksum),
              src_addr[0], src_addr[1], src_addr[2], src_addr[3],
              dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
        }
        
        /* IPv6 packet. */
        if (ipv6_header != NULL)
        {
          UINT16 *src_addr = (UINT16 *)&ipv6_header->SrcAddr;
          UINT16 *dst_addr = (UINT16 *)&ipv6_header->DstAddr;
          
          fprintf(fp, 
            "Protocol: IP (Internet Protocol)\r\n"
            "Version: %u\r\nTrafficClass: %u\r\nFlowLabel: %u\r\nLength: %u\r\n"
            "NextHdr: %u\r\nHopLimit: %u\r\nSource address: ",
              ipv6_header->Version, WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(ipv6_header),
              ntohl(WINDIVERT_IPV6HDR_GET_FLOWLABEL(ipv6_header)),
              ntohs(ipv6_header->Length), ipv6_header->NextHdr, ipv6_header->HopLimit);
          
          for (int i = 0; i < 8; i++)
            fprintf(fp, "%x%c", ntohs(src_addr[i]), (i == 7? ' ': ':'));
          fprintf(fp, "\r\nDestination address: ");
          for (int i = 0; i < 8; i++) {
            fprintf(fp, "%x", ntohs(dst_addr[i]));
            if (i != 7)
              fprintf(fp, ":");
          }
          
          fprintf(fp, "\r\n\r\n");
        }
        
        /* ICMP packet. */
        if (icmp_header != NULL)
        {
          fprintf(fp, "Protocol: ICMP (Internet Control Message Protocol)\r\n"
            "Type: %u\r\nCode: %u\r\nChecksum: 0x%.4X\r\nBody: 0x%.8X\r\n\r\n",
              icmp_header->Type, icmp_header->Code, ntohs(icmp_header->Checksum),
              ntohl(icmp_header->Body));
        }
        
        /* ICMP v6 packet. */
        if (icmpv6_header != NULL)
        {
          fprintf(fp, "Protocol: ICMP V6 (Internet Control Message Protocol)\r\n"
            "Type: %u\r\nCode: %u\r\nChecksum: 0x%.4X\r\nBody: 0x%.8X\r\n\r\n",
              icmpv6_header->Type, icmpv6_header->Code, ntohs(icmpv6_header->Checksum), 
              ntohl(icmpv6_header->Body));
        }
        
        /* TCP packet. */
        if (tcp_header != NULL)
        {
          fprintf(fp, 
            "Protocol: TCP (Transmission Control Protocol)\r\n"
            "Source port: %u\r\nDestination port: %u\r\nSequence number: %u\r\n"
            "Acknowledgment number: %u\r\nHeader length: %u\r\nReserved1: %u\r\nReserved2: %u\r\n", 
              ntohs(tcp_header->SrcPort), ntohs(tcp_header->DstPort),
              ntohl(tcp_header->SeqNum), ntohl(tcp_header->AckNum),
              tcp_header->HdrLength, tcp_header->Reserved1,
              tcp_header->Reserved2);
          
          fprintf(fp, 
            "URG: %u\r\nACK: %u\r\nPSH: %u\r\nRST: %u\r\nSYN: %u\r\nFIN: %u\r\n"
            "Window: %u\r\nChecksum: 0x%.4X\r\nUrgent Pointer: %u\r\n\r\n",
              tcp_header->Urg, tcp_header->Ack,
              tcp_header->Psh, tcp_header->Rst, tcp_header->Syn,
              tcp_header->Fin, ntohs(tcp_header->Window),
              ntohs(tcp_header->Checksum), ntohs(tcp_header->UrgPtr));
        }
        
        /* UDP packet. */
        if (udp_header != NULL)
        {
          fprintf(fp, "Protocol: UDP\r\nSource port: %u\r\nDestination port"
            ": %u\r\nLength: %u\r\nChecksum: 0x%.4X\r\n\r\n",
            ntohs(udp_header->SrcPort), ntohs(udp_header->DstPort),
            ntohs(udp_header->Length), ntohs(udp_header->Checksum));
        }
        
        /* Packet payload. */
        for (int i = 0; i < packet_len; i++)
          fprintf(fp, "%.2X", (UINT8)packet[i]);
        fprintf(fp, "\r\n\r\n");
        for (int i = 0; i < packet_len; i++) {
          if (isprint(packet[i]))
            fprintf(fp, "%c", packet[i]);
          else
            fprintf(fp, ".");
        }
        
        fprintf(fp, "\r\n\r\n");
        fclose(fp);
      }
      
      ReleaseMutex(g_mutex);
    }
  }
}