Browse Source

Initial support for WinDivert 2.0+

This patch adds WinDivert 2.0+ support in a backward-incompatible way.
WinDivert 1.4 won't work after this commit anymore.
windivert2
ValdikSS 3 years ago
parent
commit
ee4ce8893c
  1. 14
      src/fakepackets.c
  2. 82
      src/goodbyedpi.c

14
src/fakepackets.c

@ -70,19 +70,21 @@ static int send_fake_data(const HANDLE w_filter,
memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS)); memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS));
memcpy(packet_fake, pkt, packetLen); memcpy(packet_fake, pkt, packetLen);
addr_new.PseudoTCPChecksum = 0; addr_new.TCPChecksum = 0;
addr_new.PseudoIPChecksum = 0; addr_new.IPChecksum = 0;
if (!is_ipv6) { if (!is_ipv6) {
// IPv4 TCP Data packet // IPv4 TCP Data packet
if (!WinDivertHelperParsePacket(packet_fake, packetLen, &ppIpHdr, if (!WinDivertHelperParsePacket(packet_fake, packetLen, &ppIpHdr,
NULL, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen)) NULL, NULL, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen,
NULL, NULL))
return 1; return 1;
} }
else { else {
// IPv6 TCP Data packet // IPv6 TCP Data packet
if (!WinDivertHelperParsePacket(packet_fake, packetLen, NULL, if (!WinDivertHelperParsePacket(packet_fake, packetLen, NULL,
&ppIpV6Hdr, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen)) &ppIpV6Hdr, NULL, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen,
NULL, NULL))
return 1; return 1;
} }
@ -126,12 +128,12 @@ static int send_fake_data(const HANDLE w_filter,
// ...and damage it // ...and damage it
ppTcpHdr->Checksum = htons(ntohs(ppTcpHdr->Checksum) - 1); ppTcpHdr->Checksum = htons(ntohs(ppTcpHdr->Checksum) - 1);
} }
//printf("Pseudo checksum: %d\n", addr_new.PseudoTCPChecksum); //printf("Pseudo checksum: %d\n", addr_new.TCPChecksum);
WinDivertSend( WinDivertSend(
w_filter, packet_fake, w_filter, packet_fake,
packetLen_new, packetLen_new,
&addr_new, NULL NULL, &addr_new
); );
debug("Fake packet: OK"); debug("Fake packet: OK");

82
src/goodbyedpi.c

@ -518,8 +518,8 @@ static void send_native_fragment(HANDLE w_filter, WINDIVERT_ADDRESS addr,
ppTcpHdr->SeqNum = htonl(ntohl(ppTcpHdr->SeqNum) + fragment_size); ppTcpHdr->SeqNum = htonl(ntohl(ppTcpHdr->SeqNum) + fragment_size);
} }
addr.PseudoIPChecksum = 0; addr.IPChecksum = 0;
addr.PseudoTCPChecksum = 0; addr.TCPChecksum = 0;
WinDivertHelperCalcChecksums( WinDivertHelperCalcChecksums(
packet, packetLen, &addr, 0 packet, packetLen, &addr, 0
@ -527,7 +527,7 @@ static void send_native_fragment(HANDLE w_filter, WINDIVERT_ADDRESS addr,
WinDivertSend( WinDivertSend(
w_filter, packet, w_filter, packet,
packetLen, packetLen,
&addr, NULL NULL, &addr
); );
memcpy(packet, &packet_bak, orig_packetLen); memcpy(packet, &packet_bak, orig_packetLen);
//printf("Sent native fragment of %d size (step%d)\n", packetLen, step); //printf("Sent native fragment of %d size (step%d)\n", packetLen, step);
@ -1001,7 +1001,7 @@ int main(int argc, char *argv[]) {
if (do_native_frag && !(do_fragment_http || do_fragment_https)) { if (do_native_frag && !(do_fragment_http || do_fragment_https)) {
puts("\nERROR: Native fragmentation is enabled but fragment sizes are not set.\n" puts("\nERROR: Native fragmentation is enabled but fragment sizes are not set.\n"
"Fragmentation has no effect."); "Fragmentation has no effect.");
exit(EXIT_FAILURE); die();
} }
if (max_payload_size) if (max_payload_size)
@ -1038,8 +1038,8 @@ int main(int argc, char *argv[]) {
signal(SIGINT, sigint_handler); signal(SIGINT, sigint_handler);
while (1) { while (1) {
if (WinDivertRecv(w_filter, packet, sizeof(packet), &addr, &packetLen)) { if (WinDivertRecv(w_filter, packet, sizeof(packet), &packetLen, &addr)) {
debug("Got %s packet, len=%d!\n", addr.Direction ? "inbound" : "outbound", debug("Got %s packet, len=%d!\n", addr.Outbound ? "outbound" : "inbound",
packetLen); packetLen);
should_reinject = 1; should_reinject = 1;
should_recalc_checksum = 0; should_recalc_checksum = 0;
@ -1052,35 +1052,35 @@ int main(int argc, char *argv[]) {
packet_type = unknown; packet_type = unknown;
// Parse network packet and set it's type // Parse network packet and set it's type
if ((packet_v4 = WinDivertHelperParsePacket(packet, packetLen, &ppIpHdr, if (WinDivertHelperParsePacket(packet, packetLen, &ppIpHdr,
NULL, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen))) &ppIpV6Hdr, NULL, NULL, NULL, &ppTcpHdr, &ppUdpHdr, &packet_data, &packet_dataLen,
{ NULL, NULL))
packet_type = ipv4_tcp_data;
}
else if ((packet_v6 = WinDivertHelperParsePacket(packet, packetLen, NULL,
&ppIpV6Hdr, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen)))
{
packet_type = ipv6_tcp_data;
}
else if ((packet_v4 = WinDivertHelperParsePacket(packet, packetLen, &ppIpHdr,
NULL, NULL, NULL, &ppTcpHdr, NULL, NULL, NULL)))
{
packet_type = ipv4_tcp;
}
else if ((packet_v6 = WinDivertHelperParsePacket(packet, packetLen, NULL,
&ppIpV6Hdr, NULL, NULL, &ppTcpHdr, NULL, NULL, NULL)))
{
packet_type = ipv6_tcp;
}
else if ((packet_v4 = WinDivertHelperParsePacket(packet, packetLen, &ppIpHdr,
NULL, NULL, NULL, NULL, &ppUdpHdr, &packet_data, &packet_dataLen)))
{
packet_type = ipv4_udp_data;
}
else if ((packet_v6 = WinDivertHelperParsePacket(packet, packetLen, NULL,
&ppIpV6Hdr, NULL, NULL, NULL, &ppUdpHdr, &packet_data, &packet_dataLen)))
{ {
packet_type = ipv6_udp_data; if (ppIpHdr) {
packet_v4 = 1;
if (ppTcpHdr) {
packet_type = ipv4_tcp;
if (packet_data) {
packet_type = ipv4_tcp_data;
}
}
else if (ppUdpHdr && packet_data) {
packet_type = ipv4_udp_data;
}
}
else if (ppIpV6Hdr) {
packet_v6 = 1;
if (ppTcpHdr) {
packet_type = ipv6_tcp;
if (packet_data) {
packet_type = ipv6_tcp_data;
}
}
else if (ppUdpHdr && packet_data) {
packet_type = ipv6_udp_data;
}
}
} }
debug("packet_type: %d, packet_v4: %d, packet_v6: %d\n", packet_type, packet_v4, packet_v6); debug("packet_type: %d, packet_v4: %d, packet_v6: %d\n", packet_type, packet_v4, packet_v6);
@ -1090,7 +1090,7 @@ int main(int argc, char *argv[]) {
/* Got a TCP packet WITH DATA */ /* Got a TCP packet WITH DATA */
/* Handle INBOUND packet with data and find HTTP REDIRECT in there */ /* Handle INBOUND packet with data and find HTTP REDIRECT in there */
if (addr.Direction == WINDIVERT_DIRECTION_INBOUND && packet_dataLen > 16) { if (!addr.Outbound && packet_dataLen > 16) {
/* If INBOUND packet with DATA (tcp.Ack) */ /* If INBOUND packet with DATA (tcp.Ack) */
/* Drop packets from filter with HTTP 30x Redirect */ /* Drop packets from filter with HTTP 30x Redirect */
@ -1114,7 +1114,7 @@ int main(int argc, char *argv[]) {
/* Handle OUTBOUND packet on port 443, search for something that resembles /* Handle OUTBOUND packet on port 443, search for something that resembles
* TLS handshake, send fake request. * TLS handshake, send fake request.
*/ */
else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND && else if (addr.Outbound &&
((do_fragment_https ? packet_dataLen == https_fragment_size : 0) || ((do_fragment_https ? packet_dataLen == https_fragment_size : 0) ||
packet_dataLen > 16) && packet_dataLen > 16) &&
ppTcpHdr->DstPort != htons(80) && ppTcpHdr->DstPort != htons(80) &&
@ -1158,7 +1158,7 @@ int main(int argc, char *argv[]) {
} }
} }
/* Handle OUTBOUND packet on port 80, search for Host header */ /* Handle OUTBOUND packet on port 80, search for Host header */
else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND && else if (addr.Outbound &&
packet_dataLen > 16 && packet_dataLen > 16 &&
(do_http_allports ? 1 : (ppTcpHdr->DstPort == htons(80))) && (do_http_allports ? 1 : (ppTcpHdr->DstPort == htons(80))) &&
find_http_method_end(packet_data, find_http_method_end(packet_data,
@ -1302,7 +1302,7 @@ int main(int argc, char *argv[]) {
/* Else if we got TCP packet without data */ /* Else if we got TCP packet without data */
else if (packet_type == ipv4_tcp || packet_type == ipv6_tcp) { else if (packet_type == ipv4_tcp || packet_type == ipv6_tcp) {
/* If we got INBOUND SYN+ACK packet */ /* If we got INBOUND SYN+ACK packet */
if (addr.Direction == WINDIVERT_DIRECTION_INBOUND && if (!addr.Outbound &&
ppTcpHdr->Syn == 1 && ppTcpHdr->Ack == 1) { ppTcpHdr->Syn == 1 && ppTcpHdr->Ack == 1) {
//printf("Changing Window Size!\n"); //printf("Changing Window Size!\n");
/* /*
@ -1342,7 +1342,7 @@ int main(int argc, char *argv[]) {
else if ((do_dnsv4_redirect && (packet_type == ipv4_udp_data)) || else if ((do_dnsv4_redirect && (packet_type == ipv4_udp_data)) ||
(do_dnsv6_redirect && (packet_type == ipv6_udp_data))) (do_dnsv6_redirect && (packet_type == ipv6_udp_data)))
{ {
if (addr.Direction == WINDIVERT_DIRECTION_INBOUND) { if (!addr.Outbound) {
if ((packet_v4 && dns_handle_incoming(&ppIpHdr->DstAddr, ppUdpHdr->DstPort, if ((packet_v4 && dns_handle_incoming(&ppIpHdr->DstAddr, ppUdpHdr->DstPort,
packet_data, packet_dataLen, packet_data, packet_dataLen,
&dns_conn_info, 0)) &dns_conn_info, 0))
@ -1372,7 +1372,7 @@ int main(int argc, char *argv[]) {
} }
} }
else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND) { else if (addr.Outbound) {
if ((packet_v4 && dns_handle_outgoing(&ppIpHdr->SrcAddr, ppUdpHdr->SrcPort, if ((packet_v4 && dns_handle_outgoing(&ppIpHdr->SrcAddr, ppUdpHdr->SrcPort,
&ppIpHdr->DstAddr, ppUdpHdr->DstPort, &ppIpHdr->DstAddr, ppUdpHdr->DstPort,
packet_data, packet_dataLen, 0)) packet_data, packet_dataLen, 0))
@ -1410,7 +1410,7 @@ int main(int argc, char *argv[]) {
if (should_recalc_checksum) { if (should_recalc_checksum) {
WinDivertHelperCalcChecksums(packet, packetLen, &addr, (UINT64)0LL); WinDivertHelperCalcChecksums(packet, packetLen, &addr, (UINT64)0LL);
} }
WinDivertSend(w_filter, packet, packetLen, &addr, NULL); WinDivertSend(w_filter, packet, packetLen, NULL, &addr);
} }
} }
else { else {

Loading…
Cancel
Save