/* * 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); } }
/* 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); } } }