From ee4ce8893cff17204d8e758396a632e5e35cbf4f Mon Sep 17 00:00:00 2001 From: ValdikSS Date: Mon, 3 Jan 2022 21:23:40 +0300 Subject: [PATCH 1/3] 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. --- src/fakepackets.c | 14 ++++---- src/goodbyedpi.c | 82 +++++++++++++++++++++++------------------------ 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/fakepackets.c b/src/fakepackets.c index 214f575..6d59cd8 100644 --- a/src/fakepackets.c +++ b/src/fakepackets.c @@ -70,19 +70,21 @@ static int send_fake_data(const HANDLE w_filter, memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS)); memcpy(packet_fake, pkt, packetLen); - addr_new.PseudoTCPChecksum = 0; - addr_new.PseudoIPChecksum = 0; + addr_new.TCPChecksum = 0; + addr_new.IPChecksum = 0; if (!is_ipv6) { // IPv4 TCP Data packet 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; } else { // IPv6 TCP Data packet 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; } @@ -126,12 +128,12 @@ static int send_fake_data(const HANDLE w_filter, // ...and damage it ppTcpHdr->Checksum = htons(ntohs(ppTcpHdr->Checksum) - 1); } - //printf("Pseudo checksum: %d\n", addr_new.PseudoTCPChecksum); + //printf("Pseudo checksum: %d\n", addr_new.TCPChecksum); WinDivertSend( w_filter, packet_fake, packetLen_new, - &addr_new, NULL + NULL, &addr_new ); debug("Fake packet: OK"); diff --git a/src/goodbyedpi.c b/src/goodbyedpi.c index 9d18ee0..a1b42af 100644 --- a/src/goodbyedpi.c +++ b/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); } - addr.PseudoIPChecksum = 0; - addr.PseudoTCPChecksum = 0; + addr.IPChecksum = 0; + addr.TCPChecksum = 0; WinDivertHelperCalcChecksums( packet, packetLen, &addr, 0 @@ -527,7 +527,7 @@ static void send_native_fragment(HANDLE w_filter, WINDIVERT_ADDRESS addr, WinDivertSend( w_filter, packet, packetLen, - &addr, NULL + NULL, &addr ); memcpy(packet, &packet_bak, orig_packetLen); //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)) { puts("\nERROR: Native fragmentation is enabled but fragment sizes are not set.\n" "Fragmentation has no effect."); - exit(EXIT_FAILURE); + die(); } if (max_payload_size) @@ -1038,8 +1038,8 @@ int main(int argc, char *argv[]) { signal(SIGINT, sigint_handler); while (1) { - if (WinDivertRecv(w_filter, packet, sizeof(packet), &addr, &packetLen)) { - debug("Got %s packet, len=%d!\n", addr.Direction ? "inbound" : "outbound", + if (WinDivertRecv(w_filter, packet, sizeof(packet), &packetLen, &addr)) { + debug("Got %s packet, len=%d!\n", addr.Outbound ? "outbound" : "inbound", packetLen); should_reinject = 1; should_recalc_checksum = 0; @@ -1052,35 +1052,35 @@ int main(int argc, char *argv[]) { packet_type = unknown; // Parse network packet and set it's type - if ((packet_v4 = WinDivertHelperParsePacket(packet, packetLen, &ppIpHdr, - NULL, NULL, NULL, &ppTcpHdr, NULL, &packet_data, &packet_dataLen))) + if (WinDivertHelperParsePacket(packet, packetLen, &ppIpHdr, + &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); @@ -1090,7 +1090,7 @@ int main(int argc, char *argv[]) { /* Got a TCP packet WITH DATA */ /* 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) */ /* 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 * 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) || packet_dataLen > 16) && ppTcpHdr->DstPort != htons(80) && @@ -1158,7 +1158,7 @@ int main(int argc, char *argv[]) { } } /* Handle OUTBOUND packet on port 80, search for Host header */ - else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND && + else if (addr.Outbound && packet_dataLen > 16 && (do_http_allports ? 1 : (ppTcpHdr->DstPort == htons(80))) && 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 (packet_type == ipv4_tcp || packet_type == ipv6_tcp) { /* If we got INBOUND SYN+ACK packet */ - if (addr.Direction == WINDIVERT_DIRECTION_INBOUND && + if (!addr.Outbound && ppTcpHdr->Syn == 1 && ppTcpHdr->Ack == 1) { //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)) || (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, packet_data, packet_dataLen, &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, &ppIpHdr->DstAddr, ppUdpHdr->DstPort, packet_data, packet_dataLen, 0)) @@ -1410,7 +1410,7 @@ int main(int argc, char *argv[]) { if (should_recalc_checksum) { WinDivertHelperCalcChecksums(packet, packetLen, &addr, (UINT64)0LL); } - WinDivertSend(w_filter, packet, packetLen, &addr, NULL); + WinDivertSend(w_filter, packet, packetLen, NULL, &addr); } } else { From 4a8f7ac4fb3d78e884da653a9635899b5d7bb97b Mon Sep 17 00:00:00 2001 From: ValdikSS Date: Tue, 4 Jan 2022 03:14:47 +0300 Subject: [PATCH 2/3] Call WinDivertShutdown on shutdown --- src/goodbyedpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/goodbyedpi.c b/src/goodbyedpi.c index a1b42af..2635860 100644 --- a/src/goodbyedpi.c +++ b/src/goodbyedpi.c @@ -309,6 +309,7 @@ static HANDLE init(char *filter, UINT64 flags) { static int deinit(HANDLE handle) { if (handle) { + WinDivertShutdown(handle, WINDIVERT_SHUTDOWN_BOTH); WinDivertClose(handle); return TRUE; } From 68a68aede9c1d68e98c16a2bc276a158eed28d86 Mon Sep 17 00:00:00 2001 From: ValdikSS Date: Tue, 4 Jan 2022 15:06:54 +0300 Subject: [PATCH 3/3] Use WinDivert 2.2.0 for Github Actions building --- .github/workflows/build.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a24d17..ecf02f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,9 +6,10 @@ on: - 'src/**' env: - WINDIVERT_URL: https://www.reqrypt.org/download/WinDivert-1.4.3-A.zip - WINDIVERT_NAME: WinDivert-1.4.3-A.zip - WINDIVERT_SHA256: 4084bc3931f31546d375ed89e3f842776efa46f321ed0adcd32d3972a7d02566 + WINDIVERT_URL: https://www.reqrypt.org/download/WinDivert-2.2.0-A.zip + WINDIVERT_NAME: WinDivert-2.2.0-A.zip + WINDIVERT_BASENAME: WinDivert-2.2.0-A + WINDIVERT_SHA256: 2a7630aac0914746fbc565ac862fa096e3e54233883ac52d17c83107496b7a7f jobs: build: @@ -46,14 +47,14 @@ jobs: - name: Compile x86_64 run: > cd src && make clean && - make CPREFIX=x86_64-w64-mingw32- BIT64=1 WINDIVERTHEADERS=../WinDivert-1.4.3-A/include WINDIVERTLIBS=../WinDivert-1.4.3-A/x86_64 -j4 + make CPREFIX=x86_64-w64-mingw32- BIT64=1 WINDIVERTHEADERS=../${{ env.WINDIVERT_BASENAME }}/include WINDIVERTLIBS=../${{ env.WINDIVERT_BASENAME }}/x64 -j4 - name: Prepare x86_64 directory run: | mkdir goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }} - cp src/goodbyedpi.exe WinDivert-1.4.3-A/x86_64/*.{dll,sys} goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }} + cp src/goodbyedpi.exe ${{ env.WINDIVERT_BASENAME }}/x64/*.{dll,sys} goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }} - - name: Upload output file x86_64 (64 bit) + - name: Upload output file x86_64 uses: actions/upload-artifact@v2 with: name: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }} @@ -62,12 +63,12 @@ jobs: - name: Compile i686 run: > cd src && make clean && - make CPREFIX=i686-w64-mingw32- WINDIVERTHEADERS=../WinDivert-1.4.3-A/include WINDIVERTLIBS=../WinDivert-1.4.3-A/x86 -j4 + make CPREFIX=i686-w64-mingw32- WINDIVERTHEADERS=../${{ env.WINDIVERT_BASENAME }}/include WINDIVERTLIBS=../${{ env.WINDIVERT_BASENAME }}/x86 -j4 - name: Prepare x86 directory run: | mkdir goodbyedpi_x86_${{ steps.vars.outputs.sha_short }} - cp src/goodbyedpi.exe WinDivert-1.4.3-A/x86/*.{dll,sys} goodbyedpi_x86_${{ steps.vars.outputs.sha_short }} + cp src/goodbyedpi.exe ${{ env.WINDIVERT_BASENAME }}/x86/*.{dll,sys} goodbyedpi_x86_${{ steps.vars.outputs.sha_short }} - name: Upload output file x86 uses: actions/upload-artifact@v2