From 32af280adde39cff0a2fd128f211426a1a8ccf8e Mon Sep 17 00:00:00 2001 From: Zhou Yicheng Date: Fri, 19 Jun 2020 11:00:36 +0800 Subject: [PATCH 01/11] Install provider to pass HLK test --- sys/windivert.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sys/windivert.c b/sys/windivert.c index ff3006a..98e12c9 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -333,6 +333,7 @@ extern VOID windivert_worker(IN WDFWORKITEM item); static void windivert_read_service(context_t context); extern VOID windivert_create(IN WDFDEVICE device, IN WDFREQUEST request, IN WDFFILEOBJECT object); +static NTSTATUS windivert_install_provider(); static NTSTATUS windivert_install_sublayer(layer_t layer); static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer, UINT64 flags); @@ -499,6 +500,15 @@ extern void windivert_reflect_worker(IN WDFWORKITEM item); static void windivert_log_event(PEPROCESS process, PDRIVER_OBJECT driver, const wchar_t *msg_str); +/* + * WinDivert provider GUIDs + */ +DEFINE_GUID(WINDIVERT_PROVIDER_GUID, + 0x397b8b8f, 0xb710, 0x4f4e, + 0xa8, 0x58, 0x38, 0x20, 0x40, 0xb7, 0x93, 0x2d); +#define WINDIVERT_PROVIDER_NAME L"WinDivert" +#define WINDIVERT_PROVIDER_DESC L"WinDivert driver" + /* * WinDivert sublayer GUIDs */ @@ -1158,6 +1168,12 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj, DEBUG_ERROR("failed to begin WFP transaction", status); goto driver_entry_exit; } + status = windivert_install_provider(); + if (!NT_SUCCESS(status)) + { + DEBUG_ERROR("failed to install provider", status); + goto driver_entry_exit; + } status = windivert_install_sublayer(WINDIVERT_LAYER_INBOUND_NETWORK_IPV4); if (!NT_SUCCESS(status)) { @@ -1386,6 +1402,10 @@ static void windivert_driver_unload(void) WINDIVERT_LAYER_AUTH_RECV_ACCEPT_IPV4->sublayer_guid); FwpmSubLayerDeleteByKey0(engine_handle, WINDIVERT_LAYER_AUTH_RECV_ACCEPT_IPV6->sublayer_guid); + + FwpmProviderDeleteByKey0(engine_handle, + &WINDIVERT_PROVIDER_GUID); + status = FwpmTransactionCommit0(engine_handle); if (!NT_SUCCESS(status)) { @@ -1395,6 +1415,26 @@ static void windivert_driver_unload(void) } } +/* + * Register provider. + */ +static NTSTATUS windivert_install_provider() +{ + FWPM_PROVIDER0 provider; + NTSTATUS status; + + RtlZeroMemory(&provider, sizeof(provider)); + provider.providerKey = WINDIVERT_PROVIDER_GUID; + provider.displayData.name = WINDIVERT_PROVIDER_NAME; + provider.displayData.description = WINDIVERT_PROVIDER_DESC; + provider.flags = FWPM_PROVIDER_FLAG_PERSISTENT; + + // We don't care about the install result as this provider + // is only for passing HLK test. + FwpmProviderAdd0(engine_handle, &provider, NULL); + return STATUS_SUCCESS; +} + /* * Register a sub-layer. */ From 97056af2566964075469d64e140ea577e55a7ab1 Mon Sep 17 00:00:00 2001 From: basil00 Date: Fri, 26 Jun 2020 08:53:18 +0800 Subject: [PATCH 02/11] Cleanup the provider code. --- sys/windivert.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sys/windivert.c b/sys/windivert.c index 98e12c9..5394f72 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -504,10 +504,10 @@ static void windivert_log_event(PEPROCESS process, PDRIVER_OBJECT driver, * WinDivert provider GUIDs */ DEFINE_GUID(WINDIVERT_PROVIDER_GUID, - 0x397b8b8f, 0xb710, 0x4f4e, - 0xa8, 0x58, 0x38, 0x20, 0x40, 0xb7, 0x93, 0x2d); -#define WINDIVERT_PROVIDER_NAME L"WinDivert" -#define WINDIVERT_PROVIDER_DESC L"WinDivert driver" + 0x450EC398, 0x1EAF, 0x49F5, + 0x85, 0xE0, 0x22, 0x8F, 0x0D, 0x29, 0x39, 0x21); +#define WINDIVERT_PROVIDER_NAME WINDIVERT_DEVICE_NAME +#define WINDIVERT_PROVIDER_DESC WINDIVERT_DEVICE_NAME L" provider" /* * WinDivert sublayer GUIDs @@ -1424,10 +1424,9 @@ static NTSTATUS windivert_install_provider() NTSTATUS status; RtlZeroMemory(&provider, sizeof(provider)); - provider.providerKey = WINDIVERT_PROVIDER_GUID; - provider.displayData.name = WINDIVERT_PROVIDER_NAME; + provider.providerKey = WINDIVERT_PROVIDER_GUID; + provider.displayData.name = WINDIVERT_PROVIDER_NAME; provider.displayData.description = WINDIVERT_PROVIDER_DESC; - provider.flags = FWPM_PROVIDER_FLAG_PERSISTENT; // We don't care about the install result as this provider // is only for passing HLK test. From 134dd37bd0a87d3d236214e42edc1867b8911c6f Mon Sep 17 00:00:00 2001 From: basil00 Date: Thu, 3 Sep 2020 08:12:39 +0800 Subject: [PATCH 03/11] Insert all WinDivert sublayers at the max weight. --- sys/windivert.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/sys/windivert.c b/sys/windivert.c index 5394f72..43fb268 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -690,7 +690,7 @@ static const struct layer_s windivert_layer_resource_assignment_ipv4 = &WINDIVERT_SUBLAYER_RESOURCE_ASSIGNMENT_IPV4_GUID, windivert_resource_assignment_v4_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_RESOURCE_ASSIGNMENT_IPV4 \ (&windivert_layer_resource_assignment_ipv4) @@ -707,7 +707,7 @@ static const struct layer_s windivert_layer_resource_assignment_ipv6 = &WINDIVERT_SUBLAYER_RESOURCE_ASSIGNMENT_IPV6_GUID, windivert_resource_assignment_v6_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_RESOURCE_ASSIGNMENT_IPV6 \ (&windivert_layer_resource_assignment_ipv6) @@ -724,7 +724,7 @@ static const struct layer_s windivert_layer_resource_release_ipv4 = &WINDIVERT_SUBLAYER_RESOURCE_RELEASE_IPV4_GUID, windivert_resource_release_v4_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_RESOURCE_RELEASE_IPV4 \ (&windivert_layer_resource_release_ipv4) @@ -741,7 +741,7 @@ static const struct layer_s windivert_layer_resource_release_ipv6 = &WINDIVERT_SUBLAYER_RESOURCE_RELEASE_IPV6_GUID, windivert_resource_release_v6_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_RESOURCE_RELEASE_IPV6 \ (&windivert_layer_resource_release_ipv6) @@ -758,7 +758,7 @@ static const struct layer_s windivert_layer_auth_connect_ipv4 = &WINDIVERT_SUBLAYER_AUTH_CONNECT_IPV4_GUID, windivert_auth_connect_v4_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_AUTH_CONNECT_IPV4 \ (&windivert_layer_auth_connect_ipv4) @@ -775,7 +775,7 @@ static const struct layer_s windivert_layer_auth_connect_ipv6 = &WINDIVERT_SUBLAYER_AUTH_CONNECT_IPV6_GUID, windivert_auth_connect_v6_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_AUTH_CONNECT_IPV6 \ (&windivert_layer_auth_connect_ipv6) @@ -792,7 +792,7 @@ static const struct layer_s windivert_layer_endpoint_closure_ipv4 = &WINDIVERT_SUBLAYER_ENDPOINT_CLOSURE_IPV4_GUID, windivert_endpoint_closure_v4_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_ENDPOINT_CLOSURE_IPV4 \ (&windivert_layer_endpoint_closure_ipv4) @@ -809,7 +809,7 @@ static const struct layer_s windivert_layer_endpoint_closure_ipv6 = &WINDIVERT_SUBLAYER_ENDPOINT_CLOSURE_IPV6_GUID, windivert_endpoint_closure_v6_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_ENDPOINT_CLOSURE_IPV6 \ (&windivert_layer_endpoint_closure_ipv6) @@ -826,7 +826,7 @@ static const struct layer_s windivert_layer_auth_listen_ipv4 = &WINDIVERT_SUBLAYER_AUTH_LISTEN_IPV4_GUID, windivert_auth_listen_v4_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_AUTH_LISTEN_IPV4 \ (&windivert_layer_auth_listen_ipv4) @@ -843,7 +843,7 @@ static const struct layer_s windivert_layer_auth_listen_ipv6 = &WINDIVERT_SUBLAYER_AUTH_LISTEN_IPV6_GUID, windivert_auth_listen_v6_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_AUTH_LISTEN_IPV6 \ (&windivert_layer_auth_listen_ipv6) @@ -860,7 +860,7 @@ static const struct layer_s windivert_layer_auth_recv_accept_ipv4 = &WINDIVERT_SUBLAYER_AUTH_RECV_ACCEPT_IPV4_GUID, windivert_auth_recv_accept_v4_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_AUTH_RECV_ACCEPT_IPV4 \ (&windivert_layer_auth_recv_accept_ipv4) @@ -877,7 +877,7 @@ static const struct layer_s windivert_layer_auth_recv_accept_ipv6 = &WINDIVERT_SUBLAYER_AUTH_RECV_ACCEPT_IPV6_GUID, windivert_auth_recv_accept_v6_classify, NULL, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_AUTH_RECV_ACCEPT_IPV6 \ (&windivert_layer_auth_recv_accept_ipv6) @@ -894,7 +894,7 @@ static const struct layer_s windivert_layer_flow_established_ipv4 = &WINDIVERT_SUBLAYER_FLOW_ESTABLISHED_IPV4_GUID, windivert_flow_established_v4_classify, windivert_flow_delete_notify, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_FLOW_ESTABLISHED_IPV4 \ (&windivert_layer_flow_established_ipv4) @@ -911,7 +911,7 @@ static const struct layer_s windivert_layer_flow_established_ipv6 = &WINDIVERT_SUBLAYER_FLOW_ESTABLISHED_IPV6_GUID, windivert_flow_established_v6_classify, windivert_flow_delete_notify, - 0 + UINT16_MAX }; #define WINDIVERT_LAYER_FLOW_ESTABLISHED_IPV6 \ (&windivert_layer_flow_established_ipv6) From 227a6b1e7874e2835ee0677826d79fddc37e2f95 Mon Sep 17 00:00:00 2001 From: basil00 Date: Sat, 11 Sep 2021 07:09:51 +0800 Subject: [PATCH 04/11] Fix #283 --- sys/windivert.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/windivert.c b/sys/windivert.c index 43fb268..536be73 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -4061,7 +4061,7 @@ static void windivert_flow_established_v6_classify( UNREFERENCED_PARAMETER(data); UNREFERENCED_PARAMETER(flow_context); - flow_data.ProcessId = (UINT32)meta_vals->processId; + flow_data.EndpointId = meta_vals->transportEndpointHandle; flow_data.ParentEndpointId = meta_vals->parentEndpointHandle; flow_data.ProcessId = (UINT32)meta_vals->processId; windivert_get_ipv6_addr(fixed_vals, From c26ec39465d775f49f5dfc77a2612a289e4e74ed Mon Sep 17 00:00:00 2001 From: basil00 Date: Sat, 25 Sep 2021 07:23:08 +0800 Subject: [PATCH 05/11] Fix filter compiler test simplification logic Fix #285 --- dll/windivert_helper.c | 187 +++++++++++++++++++++++++++++------------ test/test.c | 4 +- 2 files changed, 137 insertions(+), 54 deletions(-) diff --git a/dll/windivert_helper.c b/dll/windivert_helper.c index 076f961..0bba154 100644 --- a/dll/windivert_helper.c +++ b/dll/windivert_helper.c @@ -1,6 +1,6 @@ /* * windivert_helper.c - * (C) 2019, all rights reserved, + * (C) 2021, all rights reserved, * * This file is part of WinDivert. * @@ -1061,7 +1061,10 @@ static PEXPR WinDivertMakeVar(KIND kind, PERROR error) } return (PEXPR)(vars + mid); } - *error = MAKE_ERROR(WINDIVERT_ERROR_ASSERTION_FAILED, 0); + if (error != NULL) + { + *error = MAKE_ERROR(WINDIVERT_ERROR_ASSERTION_FAILED, 0); + } return NULL; } @@ -1091,6 +1094,15 @@ static PEXPR WinDivertMakeZero(void) return (PEXPR)&zero; } +/* + * Construct one. + */ +static PEXPR WinDivertMakeOne(void) +{ + static const EXPR one = {{{1, 0, 0, 0}}, TOKEN_NUMBER}; + return (PEXPR)&one; +} + /* * Construct a number. */ @@ -1480,16 +1492,17 @@ static PEXPR WinDivertParseFilter(HANDLE pool, TOKEN *toks, UINT *i, INT depth, } /* - * Statically evaluate a test if possible. + * Simplify a test if possible. */ -static BOOL WinDivertEvalTest(PEXPR test, BOOL *res) +static void WinDivertSimplifyTest(PEXPR test) { PEXPR var = test->arg[0]; PEXPR val = test->arg[1]; BOOL neg_lb = FALSE, neg_ub = FALSE, neg; UINT32 lb[4] = {0}, ub[4] = {0}; int result_lb, result_ub; - BOOL eq = FALSE; + BOOL eq = FALSE, result = FALSE; + KIND type = TOKEN_TRUE; switch (var->kind) { @@ -1512,6 +1525,20 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res) case TOKEN_EVENT: lb[0] = 0; ub[0] = WINDIVERT_EVENT_MAX; break; + case TOKEN_IP_DF: + case TOKEN_IP_MF: + type = TOKEN_IP; + lb[0] = 0; ub[0] = 1; + break; + case TOKEN_TCP_URG: + case TOKEN_TCP_ACK: + case TOKEN_TCP_PSH: + case TOKEN_TCP_RST: + case TOKEN_TCP_SYN: + case TOKEN_TCP_FIN: + type = TOKEN_TCP; + lb[0] = 0; ub[0] = 1; + break; case TOKEN_INBOUND: case TOKEN_OUTBOUND: case TOKEN_FRAGMENT: @@ -1521,62 +1548,95 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res) case TOKEN_ICMPV6: case TOKEN_TCP: case TOKEN_UDP: - case TOKEN_IP_DF: - case TOKEN_IP_MF: - case TOKEN_TCP_URG: - case TOKEN_TCP_ACK: - case TOKEN_TCP_PSH: - case TOKEN_TCP_RST: - case TOKEN_TCP_SYN: - case TOKEN_TCP_FIN: lb[0] = 0; ub[0] = 1; break; case TOKEN_IP_HDR_LENGTH: + type = TOKEN_IP; + lb[0] = 0; ub[0] = 0x0F; + break; case TOKEN_TCP_HDR_LENGTH: + type = TOKEN_TCP; lb[0] = 0; ub[0] = 0x0F; break; case TOKEN_IP_TTL: case TOKEN_IP_PROTOCOL: + type = TOKEN_IP; + lb[0] = 0; ub[0] = 0xFF; + break; case TOKEN_IPV6_TRAFFIC_CLASS: case TOKEN_IPV6_NEXT_HDR: case TOKEN_IPV6_HOP_LIMIT: + type = TOKEN_IPV6; + lb[0] = 0; ub[0] = 0xFF; + break; case TOKEN_ICMP_TYPE: case TOKEN_ICMP_CODE: + type = TOKEN_ICMP; + lb[0] = 0; ub[0] = 0xFF; + break; case TOKEN_ICMPV6_TYPE: case TOKEN_ICMPV6_CODE: + type = TOKEN_ICMPV6; + lb[0] = 0; ub[0] = 0xFF; + break; + case TOKEN_TCP_PAYLOAD: + type = TOKEN_TCP; + lb[0] = 0; ub[0] = 0xFF; + break; + case TOKEN_UDP_PAYLOAD: + type = TOKEN_UDP; + lb[0] = 0; ub[0] = 0xFF; + break; case TOKEN_PROTOCOL: case TOKEN_PACKET: - case TOKEN_TCP_PAYLOAD: - case TOKEN_UDP_PAYLOAD: case TOKEN_RANDOM8: lb[0] = 0; ub[0] = 0xFF; break; case TOKEN_IP_FRAG_OFF: + type = TOKEN_IP; lb[0] = 0; ub[0] = 0x1FFF; break; case TOKEN_IP_TOS: case TOKEN_IP_LENGTH: case TOKEN_IP_ID: case TOKEN_IP_CHECKSUM: + type = TOKEN_IP; + lb[0] = 0; ub[0] = 0xFFFF; + break; case TOKEN_IPV6_LENGTH: + type = TOKEN_IPV6; + lb[0] = 0; ub[0] = 0xFFFF; + break; case TOKEN_ICMP_CHECKSUM: + type = TOKEN_ICMP; + lb[0] = 0; ub[0] = 0xFFFF; + break; case TOKEN_ICMPV6_CHECKSUM: + type = TOKEN_ICMPV6; + lb[0] = 0; ub[0] = 0xFFFF; + break; case TOKEN_TCP_SRC_PORT: case TOKEN_TCP_DST_PORT: case TOKEN_TCP_WINDOW: case TOKEN_TCP_CHECKSUM: case TOKEN_TCP_URG_PTR: case TOKEN_TCP_PAYLOAD_LENGTH: + case TOKEN_TCP_PAYLOAD16: + type = TOKEN_TCP; + lb[0] = 0; ub[0] = 0xFFFF; + break; case TOKEN_UDP_SRC_PORT: case TOKEN_UDP_DST_PORT: case TOKEN_UDP_LENGTH: case TOKEN_UDP_CHECKSUM: case TOKEN_UDP_PAYLOAD_LENGTH: + case TOKEN_UDP_PAYLOAD16: + type = TOKEN_UDP; + lb[0] = 0; ub[0] = 0xFFFF; + break; case TOKEN_LOCAL_PORT: case TOKEN_REMOTE_PORT: case TOKEN_PACKET16: - case TOKEN_TCP_PAYLOAD16: - case TOKEN_UDP_PAYLOAD16: case TOKEN_RANDOM16: lb[0] = 0; ub[0] = 0xFFFF; break; @@ -1584,10 +1644,12 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res) lb[0] = sizeof(WINDIVERT_IPHDR); ub[0] = WINDIVERT_MTU_MAX; break; case TOKEN_IPV6_FLOW_LABEL: + type = TOKEN_IPV6; lb[0] = 0; ub[0] = 0x000FFFFF; break; case TOKEN_IP_SRC_ADDR: case TOKEN_IP_DST_ADDR: + type = TOKEN_IP; lb[0] = 0; lb[1] = 0xFFFF; ub[0] = 0xFFFFFFFF; @@ -1595,6 +1657,8 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res) break; case TOKEN_IPV6_SRC_ADDR: case TOKEN_IPV6_DST_ADDR: + type = TOKEN_IPV6; + // Fallthrough case TOKEN_LOCAL_ADDR: case TOKEN_REMOTE_ADDR: lb[0] = lb[1] = lb[2] = lb[3] = 0; @@ -1607,14 +1671,27 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res) ub[1] = 0x7FFFFFFF; neg_lb = TRUE; break; + case TOKEN_TCP_PAYLOAD32: + type = TOKEN_TCP; + lb[0] = 0; ub[0] = 0xFFFFFFFF; + break; + case TOKEN_UDP_PAYLOAD32: + type = TOKEN_UDP; + lb[0] = 0; ub[0] = 0xFFFFFFFF; + break; + case TOKEN_IF_IDX: + case TOKEN_SUB_IF_IDX: + case TOKEN_RANDOM32: + case TOKEN_PROCESS_ID: + lb[0] = 0; ub[0] = 0xFFFFFFFF; + break; case TOKEN_ENDPOINT_ID: case TOKEN_PARENT_ENDPOINT_ID: lb[0] = lb[1] = 0; ub[0] = ub[1] = 0xFFFFFFFF; break; default: - lb[0] = 0; ub[0] = 0xFFFFFFFF; - break; + return; } neg = (val->neg? TRUE: FALSE); result_lb = WinDivertCompare128(neg, val->val, neg_lb, lb, /*big=*/TRUE); @@ -1624,78 +1701,81 @@ static BOOL WinDivertEvalTest(PEXPR test, BOOL *res) case TOKEN_EQ: if (result_lb < 0 || result_ub > 0) { - *res = FALSE; - return TRUE; + result = FALSE; + break; } if (eq && result_lb == 0) { - *res = TRUE; - return TRUE; + result = TRUE; + break; } - return FALSE; + return; case TOKEN_NEQ: if (result_lb < 0 || result_ub > 0) { - *res = TRUE; - return TRUE; + result = TRUE; + break; } if (eq && result_lb == 0) { - *res = FALSE; - return TRUE; + result = FALSE; + break; } - return FALSE; + return; case TOKEN_LT: if (result_ub > 0) { - *res = TRUE; - return TRUE; + result = TRUE; + break; } if (result_lb <= 0) { - *res = FALSE; - return TRUE; + result = FALSE; + break; } - return FALSE; + return; case TOKEN_LEQ: if (result_ub >= 0) { - *res = TRUE; - return TRUE; + result = TRUE; + break; } if (result_lb < 0) { - *res = FALSE; - return TRUE; + result = FALSE; + break; } - return FALSE; + return; case TOKEN_GT: if (result_ub >= 0) { - *res = FALSE; - return TRUE; + result = FALSE; + break; } if (result_lb < 0) { - *res = TRUE; - return TRUE; + result = TRUE; + break; } - return FALSE; + return; case TOKEN_GEQ: if (result_ub > 0) { - *res = FALSE; - return TRUE; + result = FALSE; + break; } if (result_lb <= 0) { - *res = TRUE; - return TRUE; + result = TRUE; + break; } - return FALSE; + return; default: - return FALSE; + return; } + test->arg[0] = WinDivertMakeVar(type, NULL); + test->arg[1] = (result? WinDivertMakeOne(): WinDivertMakeZero()); + test->kind = TOKEN_EQ; } /* @@ -1705,7 +1785,6 @@ static INT16 WinDivertFlattenExpr(PEXPR expr, INT16 *label, INT16 succ, INT16 fail, PEXPR *stack) { INT16 succ1, fail1; - BOOL res; if (succ < 0 || fail < 0) { return -1; @@ -1729,9 +1808,11 @@ static INT16 WinDivertFlattenExpr(PEXPR expr, INT16 *label, INT16 succ, stack); return succ; default: - if (WinDivertEvalTest(expr, &res)) + WinDivertSimplifyTest(expr); + if (expr->kind == TOKEN_EQ && + expr->arg[0]->kind == TOKEN_TRUE) { - return (res? succ: fail); + return (expr->arg[1]->val[0] != 0? succ: fail); } if (*label >= WINDIVERT_FILTER_MAXLEN) { diff --git a/test/test.c b/test/test.c index 92f5aaa..6e60a28 100644 --- a/test/test.c +++ b/test/test.c @@ -1,6 +1,6 @@ /* * test.c - * (C) 2019, all rights reserved, + * (C) 2021, all rights reserved, * * This file is part of WinDivert. * @@ -632,6 +632,7 @@ static const struct test tests[] = {"localAddr == 10.0.0.1 && remoteAddr == 8.8.4.4 && " "localPort == 57413 && remotePort == 53 && protocol == 17", &pkt_dns_request, TRUE}, + {"ipv6.DstAddr >= ::", &pkt_dns_request, FALSE}, {"ipv6", &pkt_ipv6_tcp_syn, TRUE}, {"ip", &pkt_ipv6_tcp_syn, FALSE}, {"tcp.Syn", &pkt_ipv6_tcp_syn, TRUE}, @@ -815,6 +816,7 @@ static const struct test tests[] = {"ipv6.SrcAddr != abcd::1", &pkt_ipv6_exthdrs_udp, TRUE}, {"ipv6.SrcAddr >= abcd::1", &pkt_ipv6_exthdrs_udp, FALSE}, {"ipv6.SrcAddr > abcd::1", &pkt_ipv6_exthdrs_udp, FALSE}, + {"ipv6.DstAddr >= ::", &pkt_ipv6_exthdrs_udp, TRUE}, {"timestamp > -1", &pkt_ipv6_exthdrs_udp, TRUE}, {"udp.SrcPort == 4660 and udp.DstPort == 43690", &pkt_ipv6_exthdrs_udp, TRUE}, From ea25bab7c54f1e3be34aecb111020a883e0efa50 Mon Sep 17 00:00:00 2001 From: StalkR Date: Tue, 15 Feb 2022 19:35:18 +0100 Subject: [PATCH 06/11] windivert.html: fix 6.11 title: format not parse --- doc/windivert.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/windivert.html b/doc/windivert.html index b0d8090..eab15d9 100644 --- a/doc/windivert.html +++ b/doc/windivert.html @@ -2317,7 +2317,7 @@ to convert the result into network-byte-order.

-

6.11 WinDivertHelperParseIPv4Address

+

6.11 WinDivertHelperFormatIPv4Address

 BOOL WinDivertHelperFormatIPv4Address(

From 0b164b6ba36de75d5a689573861d54ee73a0bf19 Mon Sep 17 00:00:00 2001
From: basil00 
Date: Sat, 9 Apr 2022 09:49:45 +0800
Subject: [PATCH 07/11] Fix handling of FwpmTransaction*() errors.

Fixes #294
---
 sys/windivert.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sys/windivert.c b/sys/windivert.c
index 536be73..901367a 100644
--- a/sys/windivert.c
+++ b/sys/windivert.c
@@ -122,8 +122,7 @@ typedef enum
     WINDIVERT_CONTEXT_STATE_OPENING = 0xA0,     // Context is opening.
     WINDIVERT_CONTEXT_STATE_OPEN    = 0xB1,     // Context is open.
     WINDIVERT_CONTEXT_STATE_CLOSING = 0xC2,     // Context is closing.
-    WINDIVERT_CONTEXT_STATE_CLOSED  = 0xD3,     // Context is closed.
-    WINDIVERT_CONTEXT_STATE_INVALID = 0xE4      // Context is invalid.
+    WINDIVERT_CONTEXT_STATE_CLOSED  = 0xD3      // Context is closed.
 } context_state_t;
 struct context_s
 {

From c983d554c9c9d102176e4440ef811d2bf845e32e Mon Sep 17 00:00:00 2001
From: basil00 
Date: Sun, 10 Apr 2022 06:51:38 +0800
Subject: [PATCH 08/11] Fix previous commit 8bda0af

Fix #294

Previous commit was incomplete.
---
 sys/windivert.c | 58 ++++++++++++++++++++++++++-----------------------
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/sys/windivert.c b/sys/windivert.c
index 901367a..d5d55d2 100644
--- a/sys/windivert.c
+++ b/sys/windivert.c
@@ -1,6 +1,6 @@
 /*
  * windivert.c
- * (C) 2019, all rights reserved,
+ * (C) 2022, all rights reserved,
  *
  * This file is part of WinDivert.
  *
@@ -122,7 +122,7 @@ typedef enum
     WINDIVERT_CONTEXT_STATE_OPENING = 0xA0,     // Context is opening.
     WINDIVERT_CONTEXT_STATE_OPEN    = 0xB1,     // Context is open.
     WINDIVERT_CONTEXT_STATE_CLOSING = 0xC2,     // Context is closing.
-    WINDIVERT_CONTEXT_STATE_CLOSED  = 0xD3      // Context is closed.
+    WINDIVERT_CONTEXT_STATE_CLOSED  = 0xD3,     // Context is closed.
 } context_state_t;
 struct context_s
 {
@@ -332,7 +332,7 @@ extern VOID windivert_worker(IN WDFWORKITEM item);
 static void windivert_read_service(context_t context);
 extern VOID windivert_create(IN WDFDEVICE device, IN WDFREQUEST request,
     IN WDFFILEOBJECT object);
-static NTSTATUS windivert_install_provider();
+static NTSTATUS windivert_install_provider(void);
 static NTSTATUS windivert_install_sublayer(layer_t layer);
 static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer,
     UINT64 flags);
@@ -1165,12 +1165,14 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj,
     if (!NT_SUCCESS(status))
     {
         DEBUG_ERROR("failed to begin WFP transaction", status);
+        FwpmTransactionAbort0(engine_handle);
         goto driver_entry_exit;
     }
     status = windivert_install_provider();
     if (!NT_SUCCESS(status))
     {
         DEBUG_ERROR("failed to install provider", status);
+        FwpmTransactionAbort0(engine_handle);
         goto driver_entry_exit;
     }
     status = windivert_install_sublayer(WINDIVERT_LAYER_INBOUND_NETWORK_IPV4);
@@ -1282,6 +1284,7 @@ driver_entry_sublayer_error:
     if (!NT_SUCCESS(status))
     {
         DEBUG_ERROR("failed to commit WFP transaction", status);
+        FwpmTransactionAbort0(engine_handle);
         goto driver_entry_exit;
     }
 
@@ -1358,6 +1361,7 @@ static void windivert_driver_unload(void)
         if (!NT_SUCCESS(status))
         {
             DEBUG_ERROR("failed to begin WFP transaction", status);
+            FwpmTransactionAbort0(engine_handle);
             FwpmEngineClose0(engine_handle);
             return;
         }
@@ -1408,6 +1412,7 @@ static void windivert_driver_unload(void)
         status = FwpmTransactionCommit0(engine_handle);
         if (!NT_SUCCESS(status))
         {
+            FwpmTransactionAbort0(engine_handle);
             DEBUG_ERROR("failed to commit WFP transaction", status);
         }
         FwpmEngineClose0(engine_handle);
@@ -1567,7 +1572,7 @@ windivert_create_exit:
     // Clean-up on error:
     if (!NT_SUCCESS(status))
     {
-        context->state = WINDIVERT_CONTEXT_STATE_INVALID;
+        context->state = WINDIVERT_CONTEXT_STATE_CLOSED;
         if (context->read_queue != NULL)
         {
             WdfObjectDelete(context->read_queue);
@@ -1576,14 +1581,7 @@ windivert_create_exit:
         {
             WdfObjectDelete(context->worker);
         }
-        if (context->process != NULL)
-        {
-            ObDereferenceObject(context->process);
-        }
-        if (context->engine_handle != NULL)
-        {
-            FwpmEngineClose0(context->engine_handle);
-        }
+        // process/engine_handle handled by windivert_destroy()
     }
 
     WdfRequestComplete(request, status);
@@ -1602,15 +1600,15 @@ static NTSTATUS windivert_install_callouts(context_t context, UINT8 layer,
         accept, close;
     NTSTATUS status = STATUS_SUCCESS;
 
-    inbound    = ((flags & WINDIVERT_FILTER_FLAG_INBOUND) != 0);
-    outbound   = ((flags & WINDIVERT_FILTER_FLAG_OUTBOUND) != 0);
-    ipv4       = ((flags & WINDIVERT_FILTER_FLAG_IP) != 0);
-    ipv6       = ((flags & WINDIVERT_FILTER_FLAG_IPV6) != 0);
-    bind       = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND) != 0);
-    connect    = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT) != 0);
-    listen     = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN) != 0);
-    accept     = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT) != 0);
-    close      = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE) != 0);
+    inbound  = ((flags & WINDIVERT_FILTER_FLAG_INBOUND) != 0);
+    outbound = ((flags & WINDIVERT_FILTER_FLAG_OUTBOUND) != 0);
+    ipv4     = ((flags & WINDIVERT_FILTER_FLAG_IP) != 0);
+    ipv6     = ((flags & WINDIVERT_FILTER_FLAG_IPV6) != 0);
+    bind     = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_BIND) != 0);
+    connect  = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CONNECT) != 0);
+    listen   = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_LISTEN) != 0);
+    accept   = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_ACCEPT) != 0);
+    close    = ((flags & WINDIVERT_FILTER_FLAG_EVENT_SOCKET_CLOSE) != 0);
 
     i = 0;
     switch (layer)
@@ -1802,8 +1800,7 @@ static NTSTATUS windivert_install_callout(context_t context, UINT idx,
     if (!NT_SUCCESS(status))
     {
         DEBUG_ERROR("failed to begin WFP transaction", status);
-        FwpsCalloutUnregisterByKey0(&callout_guid);
-        return status;
+        goto windivert_install_callout_error;
     }
     status = FwpmCalloutAdd0(engine, &mcallout, NULL, NULL);
     if (!NT_SUCCESS(status))
@@ -1821,8 +1818,7 @@ static NTSTATUS windivert_install_callout(context_t context, UINT idx,
     if (!NT_SUCCESS(status))
     {
         DEBUG_ERROR("failed to commit WFP transaction", status);
-        FwpsCalloutUnregisterByKey0(&callout_guid);
-        return status;
+        goto windivert_install_callout_error;
     }
 
     KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle);
@@ -1877,6 +1873,7 @@ windivert_uninstall_callouts_error:
         // RPC handle was closed first. So, this path is "normal" if
         // the user's app crashed or never closed the WinDivert handle.
         DEBUG_ERROR("failed to begin WFP transaction", status);
+        FwpmTransactionAbort0(engine);
         goto windivert_uninstall_callouts_unregister;
     }
     for (i = 0; i < WINDIVERT_CONTEXT_MAXLAYERS; i++)
@@ -1921,6 +1918,7 @@ windivert_uninstall_callouts_error:
     if (!NT_SUCCESS(status))
     {
         DEBUG_ERROR("failed to commit WFP transaction", status);
+        FwpmTransactionAbort0(engine);
         // continue
     }
 
@@ -2103,9 +2101,15 @@ extern VOID windivert_destroy(IN WDFOBJECT object)
     filter = context->filter;
     KeReleaseInStackQueuedSpinLock(&lock_handle);
     windivert_uninstall_callouts(context, WINDIVERT_CONTEXT_STATE_CLOSED);
-    FwpmEngineClose0(context->engine_handle);
+    if (context->engine_handle != NULL)
+    {
+        FwpmEngineClose0(context->engine_handle);
+    }
     windivert_free((PVOID)filter);
-    ObDereferenceObject(context->process);
+    if (context->process != NULL)
+    {
+        ObDereferenceObject(context->process);
+    }
 }
 
 /*

From 65bb889c792147938881d1ed7786238b0c2b632f Mon Sep 17 00:00:00 2001
From: basil00 
Date: Sat, 30 Jul 2022 11:34:25 +0800
Subject: [PATCH 09/11] Bump version and copyright years

---
 VERSION             | 2 +-
 inf/windivert32.inf | 2 +-
 inf/windivert64.inf | 2 +-
 sys/windivert.rc    | 4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/VERSION b/VERSION
index ccbccc3..c043eea 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.0
+2.2.1
diff --git a/inf/windivert32.inf b/inf/windivert32.inf
index 30da774..08b1aba 100644
--- a/inf/windivert32.inf
+++ b/inf/windivert32.inf
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
 ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
 Provider = %Basil%
 CatalogFile = WinDivert32.Cat
-DriverVer = 08/08/2019,2.2.0
+DriverVer = 01/08/2022,2.2.1
 
 [SourceDisksNames]
 1 = %DiskName%
diff --git a/inf/windivert64.inf b/inf/windivert64.inf
index c5e2cdb..33888f0 100644
--- a/inf/windivert64.inf
+++ b/inf/windivert64.inf
@@ -4,7 +4,7 @@ Class = WFPCALLOUTS
 ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
 Provider = %Basil%
 CatalogFile = WinDivert64.Cat
-DriverVer = 08/08/2019,2.2.0
+DriverVer = 01/08/2022,2.2.1
 
 [SourceDisksNames]
 1 = %DiskName%
diff --git a/sys/windivert.rc b/sys/windivert.rc
index 11a4e97..775f97b 100644
--- a/sys/windivert.rc
+++ b/sys/windivert.rc
@@ -1,6 +1,6 @@
 /*
  * windivert.rc
- * (C) 2019, all rights reserved,
+ * (C) 2022, all rights reserved,
  *
  * This file is part of WinDivert.
  *
@@ -48,7 +48,7 @@
 #define VER_PRODUCTVERSION          2.2
 #define VER_PRODUCTVERSION_STR      "2.2"
 #define VER_COMPANYNAME_STR         "Basil"
-#define VER_LEGALCOPYRIGHT_YEARS    "2011-2019"
+#define VER_LEGALCOPYRIGHT_YEARS    "2011-2022"
 #define VER_LEGALCOPYRIGHT_STR      \
     "Copyright \251 " VER_COMPANYNAME_STR " " VER_LEGALCOPYRIGHT_YEARS 
 #define VER_FILEVERSION             VER_PRODUCTVERSION

From 3402f8b2f1a787e67b11e3212f1cffee3aa07b5e Mon Sep 17 00:00:00 2001
From: basil00 
Date: Mon, 12 Sep 2022 08:08:42 +0800
Subject: [PATCH 10/11] Fix #315

---
 sys/windivert.c | 61 ++++++++++++++++++++++---------------------------
 1 file changed, 27 insertions(+), 34 deletions(-)

diff --git a/sys/windivert.c b/sys/windivert.c
index d5d55d2..cca6cc9 100644
--- a/sys/windivert.c
+++ b/sys/windivert.c
@@ -273,8 +273,6 @@ struct flow_s
     UINT64 flow_id;                         // WFP flow ID.
     UINT32 callout_id;                      // WFP callout ID.
     UINT16 layer_id;                        // WFP layout ID.
-    BOOL inserted:1;                        // Flow inserted into context?
-    BOOL deleted:1;                         // Flow deleted from context?
     BOOL outbound:1;                        // Flow is outound?
     BOOL loopback:1;                        // Flow is loopback?
     BOOL ipv6:1;                            // Flow is ipv6?
@@ -1981,17 +1979,20 @@ windivert_cleanup_error:
     context->state = WINDIVERT_CONTEXT_STATE_CLOSING;
     sniff_mode = ((context->flags & WINDIVERT_FLAG_SNIFF) != 0);
     forward = (context->layer == WINDIVERT_LAYER_NETWORK_FORWARD);
-    while (!IsListEmpty(&context->flow_set))
+    entry = context->flow_set.Flink;
+    if (entry != &context->flow_set)
     {
-        entry = RemoveHeadList(&context->flow_set);
-        flow = CONTAINING_RECORD(entry, struct flow_s, entry);
-        flow->deleted = TRUE;
         KeReleaseInStackQueuedSpinLock(&lock_handle);
-        status = FwpsFlowRemoveContext0(flow->flow_id, flow->layer_id,
-            flow->callout_id);
-        if (!NT_SUCCESS(status))
+        for (; entry != &context->flow_set; entry = entry->Flink)
         {
-            windivert_free(flow);
+            flow = CONTAINING_RECORD(entry, struct flow_s, entry);
+            status = FwpsFlowRemoveContext0(flow->flow_id, flow->layer_id,
+                flow->callout_id);
+            if (!NT_SUCCESS(status) && status != STATUS_UNSUCCESSFUL)
+            {
+                // For STATUS_UNSUCCESSFUL, flow_delete() is still called.
+                WdfObjectDereference((WDFOBJECT)object);
+            }
         }
         KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle);
     }
@@ -2086,6 +2087,8 @@ extern VOID windivert_destroy(IN WDFOBJECT object)
     KLOCK_QUEUE_HANDLE lock_handle;
     context_t context = windivert_context_get((WDFFILEOBJECT)object);
     const WINDIVERT_FILTER *filter;
+    PLIST_ENTRY entry;
+    flow_t flow;
     NTSTATUS status;
 
     DEBUG("DESTROY: destroying WinDivert context (context=%p)", context);
@@ -2106,6 +2109,12 @@ extern VOID windivert_destroy(IN WDFOBJECT object)
         FwpmEngineClose0(context->engine_handle);
     }
     windivert_free((PVOID)filter);
+    while (!IsListEmpty(&context->flow_set))
+    {
+        entry = RemoveHeadList(&context->flow_set);
+        flow = CONTAINING_RECORD(entry, struct flow_s, entry);
+        windivert_free(flow);
+    }
     if (context->process != NULL)
     {
         ObDereferenceObject(context->process);
@@ -4179,22 +4188,11 @@ static void windivert_flow_established_classify(context_t context,
     flow->flow_id = flow_id;
     flow->callout_id = callout_id;
     flow->layer_id = layer_id;
-    flow->inserted = FALSE;
-    flow->deleted = FALSE;
     flow->outbound = outbound;
     flow->loopback = loopback;
     flow->ipv6 = !ipv4;
     RtlCopyMemory(&flow->data, flow_data, sizeof(flow->data));
 
-    status = FwpsFlowAssociateContext0(flow_id, layer_id, callout_id,
-        (UINT64)flow);
-    if (!NT_SUCCESS(status))
-    {
-        windivert_free(flow);
-        WdfObjectDereference(object);
-        return;
-    }
-
     KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle);
     if (context->state != WINDIVERT_CONTEXT_STATE_OPEN ||
         context->shutdown_recv)
@@ -4204,19 +4202,16 @@ static void windivert_flow_established_classify(context_t context,
         WdfObjectDereference(object);
         return;
     }
-    if (!flow->deleted)
+    status = FwpsFlowAssociateContext0(flow_id, layer_id, callout_id,
+        (UINT64)flow);
+    if (!NT_SUCCESS(status))
     {
-        InsertTailList(&context->flow_set, &flow->entry);
-        flow->inserted = TRUE;
-    }
-    else
-    {
-        // Flow was deleted before insertion; we are responsible for cleanup.
         KeReleaseInStackQueuedSpinLock(&lock_handle);
         windivert_free(flow);
         WdfObjectDereference(object);
         return;
     }
+    InsertTailList(&context->flow_set, &flow->entry);
     KeReleaseInStackQueuedSpinLock(&lock_handle);
 }
 
@@ -4243,18 +4238,16 @@ static void windivert_flow_delete_notify(UINT16 layer_id, UINT32 callout_id,
     {
         return;
     }
-
     timestamp = KeQueryPerformanceCounter(NULL).QuadPart;
     context = flow->context;
 
     KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle);
     object = (WDFOBJECT)context->object; // referenced in flow_established.
-    if (flow->inserted && !flow->deleted)
+    cleanup = (context->state == WINDIVERT_CONTEXT_STATE_OPEN);
+    if (cleanup)
     {
         RemoveEntryList(&flow->entry);
     }
-    flow->deleted = TRUE;
-    cleanup = flow->inserted;
     if (context->state != WINDIVERT_CONTEXT_STATE_OPEN ||
         context->shutdown_recv)
     {
@@ -4279,12 +4272,12 @@ static void windivert_flow_delete_notify(UINT16 layer_id, UINT32 callout_id,
     }
 
 windivert_flow_delete_notify_exit:
-
     if (cleanup)
     {
+        // If context->state != OPEN, then destroy() will free the flow.
         windivert_free(flow);
-        WdfObjectDereference(object);
     }
+    WdfObjectDereference(object);
 }
 
 /*

From 1789526ecfb9ff5397c94f9f54c1a3dc2fb60440 Mon Sep 17 00:00:00 2001
From: basil00 
Date: Sat, 17 Sep 2022 10:32:57 +0800
Subject: [PATCH 11/11] Bump version to 2.2.2 & other fixups

---
 CHANGELOG           | 6 ++++++
 README              | 2 +-
 VERSION             | 2 +-
 doc/windivert.html  | 2 +-
 inf/windivert32.inf | 2 +-
 inf/windivert64.inf | 2 +-
 6 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index bab7d43..bb7a27a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -312,3 +312,9 @@ WinDivert 2.2.0
     - Implement new packet parser that correctly handles IP fragments.
     - Add a new "fragment" filter field that matches IP fragments.
     - (Un)Loading the WinDivert driver will cause a system event to be logged.
+WinDivert 2.2.1
+    - Fix potential driver deadlock on user-mode program crash.
+    - Fix filter language simplification bug.
+    - Fix Flow.EndpointId containing junk data.
+WinDivert 2.2.2
+    - Fix potential WinDivertClose() BSOD for WINDIVERT_LAYER_FLOW handles.
diff --git a/README b/README
index 5dcbc58..14e9055 100644
--- a/README
+++ b/README
@@ -5,7 +5,7 @@ WinDivert 2.2: Windows Packet Divert
 ---------------
 
 Windows Packet Divert (WinDivert) is a user-mode packet interception library
-for Windows 7, Windows 8 and Windows 10.
+for Windows 10, Windows 11, and Windows Server.
 
 WinDivert enables user-mode capturing/modifying/dropping of network packets
 sent to/from the Windows network stack.  In summary, WinDivert can:
diff --git a/VERSION b/VERSION
index c043eea..b1b25a5 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.1
+2.2.2
diff --git a/doc/windivert.html b/doc/windivert.html
index eab15d9..85a870a 100644
--- a/doc/windivert.html
+++ b/doc/windivert.html
@@ -72,7 +72,7 @@
 

WinDivert is a powerful user-mode capture/sniffing/modification/blocking/re-injection package for -Windows 7, Windows 8 and Windows 10. +Windows 10, Windows 11, and Windows Server. WinDivert can be used to implement user-mode packet filters, packet sniffers, firewalls, NAT, VPNs, tunneling applications, etc., without the need to write kernel-mode code. diff --git a/inf/windivert32.inf b/inf/windivert32.inf index 08b1aba..031e7df 100644 --- a/inf/windivert32.inf +++ b/inf/windivert32.inf @@ -4,7 +4,7 @@ Class = WFPCALLOUTS ClassGuid = {57465043-616C-6C6F-7574-5F636C617373} Provider = %Basil% CatalogFile = WinDivert32.Cat -DriverVer = 01/08/2022,2.2.1 +DriverVer = 01/09/2022,2.2.2 [SourceDisksNames] 1 = %DiskName% diff --git a/inf/windivert64.inf b/inf/windivert64.inf index 33888f0..014ef36 100644 --- a/inf/windivert64.inf +++ b/inf/windivert64.inf @@ -4,7 +4,7 @@ Class = WFPCALLOUTS ClassGuid = {57465043-616C-6C6F-7574-5F636C617373} Provider = %Basil% CatalogFile = WinDivert64.Cat -DriverVer = 01/08/2022,2.2.1 +DriverVer = 01/09/2022,2.2.2 [SourceDisksNames] 1 = %DiskName%