Skip to content

Commit 69b4620

Browse files
committed
Log a system event on driver (un)load.
This allows WinDivert to be detected without using the REFLECT API.
1 parent bcba321 commit 69b4620

9 files changed

+184
-15
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,5 @@ WinDivert 2.1.0
310310
- Fix missing Flow.EndpointId and Flow.ParentEndpointId for IPv6 flows.
311311
WinDivert 2.2.0
312312
- Implement new packet parser that correctly handles IP fragments.
313+
- Add a new "fragment" filter field that matches IP fragments.
314+
- (Un)Loading the WinDivert driver will cause a system event to be logged.

dll/windivert.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,33 @@ static BOOLEAN WinDivertGetDriverFileName(LPWSTR sys_str)
263263
return TRUE;
264264
}
265265

266+
/*
267+
* Register event log. It is not an error if this function fails.
268+
*/
269+
static void WinDivertRegisterEventSource(const wchar_t *windivert_sys)
270+
{
271+
HKEY key;
272+
size_t len;
273+
DWORD types = 7;
274+
275+
if (!WinDivertStrLen(windivert_sys, MAX_PATH, &len))
276+
{
277+
return;
278+
}
279+
if (RegCreateKeyExA(HKEY_LOCAL_MACHINE,
280+
"System\\CurrentControlSet\\Services\\EventLog\\System\\WinDivert",
281+
0, NULL, REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &key, NULL)
282+
!= ERROR_SUCCESS)
283+
{
284+
return;
285+
}
286+
RegSetValueExW(key, L"EventMessageFile", 0, REG_SZ, (LPBYTE)windivert_sys,
287+
(len + 1) * sizeof(wchar_t));
288+
RegSetValueExA(key, "TypesSupported", 0, REG_DWORD, (LPBYTE)&types,
289+
sizeof(types));
290+
RegCloseKey(key);
291+
}
292+
266293
/*
267294
* Install the WinDivert driver.
268295
*/
@@ -324,6 +351,9 @@ static BOOLEAN WinDivertDriverInstall(VOID)
324351
goto WinDivertDriverInstallExit;
325352
}
326353

354+
// Register event logging:
355+
WinDivertRegisterEventSource(windivert_sys);
356+
327357
WinDivertDriverInstallExit:
328358

329359
success = (service != NULL);
@@ -356,7 +386,7 @@ static BOOLEAN WinDivertDriverInstall(VOID)
356386
ReleaseMutex(mutex);
357387
CloseHandle(mutex);
358388
SetLastError(err);
359-
389+
360390
return success;
361391
}
362392

dll/windivert_helper.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@
3232
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
3333
*/
3434

35-
#include <stdio.h>
36-
#include <stdlib.h>
37-
38-
39-
4035
/****************************************************************************/
4136
/* WINDIVERT HELPER IMPLEMENTATION */
4237
/****************************************************************************/
@@ -2149,8 +2144,8 @@ static BOOL WinDivertCondExecFilter(PWINDIVERT_FILTER filter, UINT length,
21492144
{
21502145
INT16 ip;
21512146
UINT16 succ, fail;
2152-
BOOL result[WINDIVERT_FILTER_MAXLEN];
2153-
BOOL result_succ, result_fail, result_test;
2147+
BOOLEAN result[WINDIVERT_FILTER_MAXLEN];
2148+
BOOLEAN result_succ, result_fail, result_test;
21542149

21552150
if (length == 0)
21562151
{

include/windivert_device.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
/*
3939
* NOTE: This is the low-level interface to the WinDivert device driver.
4040
* This interface should not be used directly, instead use the high-level
41-
* interface provided by the divert API.
41+
* interface provided by the WinDivert API.
4242
*/
4343

4444
#define WINDIVERT_KERNEL

mingw-build.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ ENVS="i686-w64-mingw32 x86_64-w64-mingw32"
4141

4242
if [ "$1" = "debug" ]
4343
then
44-
MSVCRT=-lmsvcrt
44+
EXTRA_OPTS="-lmsvcrt -include stdio.h"
4545
fi
4646

4747
for ENV in $ENVS
@@ -66,7 +66,7 @@ do
6666
CC="$ENV-gcc"
6767
COPTS="-fno-ident -shared -Wall -Wno-pointer-to-int-cast -Os -Iinclude/
6868
-Wl,--enable-stdcall-fixup -Wl,--entry=${MANGLE}WinDivertDllEntry"
69-
CLIBS="-lkernel32 -ladvapi32 $MSVCRT"
69+
CLIBS="-lkernel32 -ladvapi32 $EXTRA_OPTS"
7070
STRIP="$ENV-strip"
7171
DLLTOOL="$ENV-dlltool"
7272
if [ -x "`which $CC`" ]

sys/windivert.c

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
3333
*/
3434

35-
3635
#include <ntifs.h>
3736
#include <ntddk.h>
3837
#include <fwpsk.h>
@@ -44,6 +43,7 @@
4443
#include <guiddef.h>
4544

4645
#include "windivert_device.h"
46+
#include "windivert_log.h"
4747

4848
/*
4949
* WDK function declaration cruft.
@@ -304,6 +304,7 @@ static LONGLONG counts_per_ms = 0;
304304
static POOL_TYPE non_paged_pool = NonPagedPool;
305305
static MM_PAGE_PRIORITY no_write_flag = 0;
306306
static MM_PAGE_PRIORITY no_exec_flag = 0;
307+
static LONG64 num_opens = 0;
307308

308309
/*
309310
* Priorities.
@@ -491,6 +492,8 @@ static void windivert_reflect_event_notify(context_t context,
491492
static void windivert_reflect_established_notify(context_t context,
492493
LONGLONG timestamp);
493494
extern void windivert_reflect_worker(IN WDFWORKITEM item);
495+
static void windivert_log_event(PEPROCESS process, PDRIVER_OBJECT driver,
496+
const wchar_t *msg_str);
494497

495498
/*
496499
* WinDivert sublayer GUIDs
@@ -1245,11 +1248,11 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj,
12451248
/*
12461249
* WinDivert driver unload routine.
12471250
*/
1248-
extern VOID windivert_unload(IN WDFDRIVER driver)
1251+
extern VOID windivert_unload(IN WDFDRIVER driver_0)
12491252
{
1250-
UNREFERENCED_PARAMETER(driver);
1251-
1253+
PDRIVER_OBJECT driver = WdfDriverWdmGetDriverObject(driver_0);
12521254
windivert_driver_unload();
1255+
windivert_log_event(PsGetCurrentProcess(), driver, L"UNLOAD");
12531256
}
12541257

12551258
/*
@@ -3116,6 +3119,7 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
31163119
UINT32 process_id;
31173120
WINDIVERT_LAYER layer;
31183121
UINT8 filter_len;
3122+
WDFDEVICE device;
31193123

31203124
ioctl = (PWINDIVERT_IOCTL)inbuf;
31213125
filter_flags = ioctl->startup.flags;
@@ -3172,8 +3176,15 @@ extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request,
31723176
context->reflect.open = FALSE;
31733177
context->shutdown_recv_enabled =
31743178
(layer != WINDIVERT_LAYER_REFLECT);
3179+
device = context->device;
31753180
KeReleaseInStackQueuedSpinLock(&lock_handle);
31763181

3182+
if (InterlockedIncrement64(&num_opens) == 1)
3183+
{
3184+
PDRIVER_OBJECT driver = WdfDriverWdmGetDriverObject(
3185+
WdfDeviceGetDriver(device));
3186+
windivert_log_event(process, driver, L"LOAD");
3187+
}
31773188
windivert_reflect_open_event(context);
31783189

31793190
status = windivert_install_callouts(context, layer, filter_flags);
@@ -6182,3 +6193,67 @@ void windivert_reflect_worker(IN WDFWORKITEM item)
61826193
KeReleaseInStackQueuedSpinLock(&lock_handle);
61836194
}
61846195

6196+
/*
6197+
* Log a driver event.
6198+
*/
6199+
static void windivert_log_event(PEPROCESS process, PDRIVER_OBJECT driver,
6200+
const wchar_t *msg_str)
6201+
{
6202+
const wchar_t windivert_str[] = WINDIVERT_DEVICE_NAME
6203+
WINDIVERT_VERSION_LSTR;
6204+
wchar_t pid_str[16];
6205+
size_t windivert_size = sizeof(windivert_str), msg_size, pid_size, size;
6206+
UNICODE_STRING string;
6207+
UINT8 *str;
6208+
PIO_ERROR_LOG_PACKET packet;
6209+
NTSTATUS status;
6210+
6211+
size = ERROR_LOG_MAXIMUM_SIZE - sizeof(wchar_t) -
6212+
(sizeof(IO_ERROR_LOG_PACKET) + windivert_size + sizeof(pid_str));
6213+
status = RtlStringCbLengthW(msg_str, size, &msg_size);
6214+
if (!NT_SUCCESS(status))
6215+
{
6216+
return;
6217+
}
6218+
msg_size += sizeof(wchar_t);
6219+
6220+
if (process != NULL)
6221+
{
6222+
string.Length = 0;
6223+
string.MaximumLength = sizeof(pid_str);
6224+
string.Buffer = pid_str;
6225+
status = RtlIntegerToUnicodeString(
6226+
(UINT32)(ULONG_PTR)PsGetProcessId(process), 10, &string);
6227+
pid_size = string.Length + sizeof(wchar_t);
6228+
}
6229+
if (process == NULL || !NT_SUCCESS(status))
6230+
{
6231+
pid_str[0] = pid_str[1] = pid_str[2] = L'?';
6232+
pid_str[3] = L'\0';
6233+
pid_size = 4 * sizeof(wchar_t);
6234+
}
6235+
6236+
size = sizeof(IO_ERROR_LOG_PACKET) + windivert_size + msg_size + pid_size;
6237+
if (size > ERROR_LOG_MAXIMUM_SIZE)
6238+
{
6239+
return;
6240+
}
6241+
packet = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(driver, (UCHAR)size);
6242+
if (packet == NULL)
6243+
{
6244+
return;
6245+
}
6246+
RtlZeroMemory(packet, size);
6247+
packet->NumberOfStrings = 3;
6248+
packet->StringOffset = sizeof(IO_ERROR_LOG_PACKET);
6249+
packet->ErrorCode = WINDIVERT_INFO_EVENT;
6250+
str = (UINT8 *)packet + packet->StringOffset;
6251+
RtlCopyMemory(str, windivert_str, windivert_size);
6252+
str += windivert_size;
6253+
RtlCopyMemory(str, msg_str, msg_size);
6254+
str += msg_size;
6255+
RtlCopyMemory(str, pid_str, pid_size);
6256+
6257+
IoWriteErrorLogEntry(packet);
6258+
}
6259+

sys/windivert.rc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include <windows.h>
3636
#include <ntverp.h>
3737

38+
#include "windivert_log.rc"
39+
3840
#define VER_FILETYPE VFT_DRV
3941
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
4042
#define VER_FILEDESCRIPTION_STR \

sys/windivert.vcxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@
4545
<Platform>x64</Platform>
4646
</ProjectConfiguration>
4747
</ItemGroup>
48+
<ItemGroup>
49+
<MessageCompile Include="windivert_log.mc">
50+
<RCFilePath>.</RCFilePath>
51+
<HeaderFilePath>.</HeaderFilePath>
52+
</MessageCompile>
53+
</ItemGroup>
4854
<ItemGroup>
4955
<ResourceCompile Include="windivert.rc" />
5056
</ItemGroup>

sys/windivert_log.mc

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
;/*
2+
; * windivert_log.mc
3+
; * (C) 2019, all rights reserved,
4+
; *
5+
; * This file is part of WinDivert.
6+
; *
7+
; * WinDivert is free software: you can redistribute it and/or modify it under
8+
; * the terms of the GNU Lesser General Public License as published by the
9+
; * Free Software Foundation, either version 3 of the License, or (at your
10+
; * option) any later version.
11+
; *
12+
; * This program is distributed in the hope that it will be useful, but
13+
; * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14+
; * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15+
; * License for more details.
16+
; *
17+
; * You should have received a copy of the GNU Lesser General Public License
18+
; * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
; *
20+
; * WinDivert is free software; you can redistribute it and/or modify it under
21+
; * the terms of the GNU General Public License as published by the Free
22+
; * Software Foundation; either version 2 of the License, or (at your option)
23+
; * any later version.
24+
; *
25+
; * This program is distributed in the hope that it will be useful, but
26+
; * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27+
; * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28+
; * for more details.
29+
; *
30+
; * You should have received a copy of the GNU General Public License along
31+
; * with this program; if not, write to the Free Software Foundation, Inc., 51
32+
; * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
33+
; */
34+
35+
MessageIdTypedef=NTSTATUS
36+
37+
SeverityNames = (
38+
Success = 0x0:STATUS_SEVERITY_SUCCESS
39+
Informational = 0x1:STATUS_SEVERITY_INFORMATIONAL
40+
Warning = 0x2:STATUS_SEVERITY_WARNING
41+
Error = 0x3:STATUS_SEVERITY_ERROR
42+
)
43+
44+
FacilityNames = (
45+
System = 0x0:FACILITY_SYSTEM
46+
Runtime = 0x2:FACILITY_RUNTIME
47+
Stubs = 0x3:FACILITY_STUBS
48+
Io = 0x4:FACILITY_IO_ERROR_CODE
49+
WinDivert = 0x574:FACILITY_WINDIVERT
50+
)
51+
52+
MessageId=0x312D
53+
Facility=WinDivert
54+
Severity=Informational
55+
SymbolicName=WINDIVERT_INFO_EVENT
56+
Language=English
57+
%2 %3 (processId=%4)
58+
.
59+

0 commit comments

Comments
 (0)