Log a system event on driver (un)load.
This allows WinDivert to be detected without using the REFLECT API.
This commit is contained in:
@@ -310,3 +310,5 @@ WinDivert 2.1.0
|
||||
- Fix missing Flow.EndpointId and Flow.ParentEndpointId for IPv6 flows.
|
||||
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.
|
||||
|
||||
+31
-1
@@ -263,6 +263,33 @@ static BOOLEAN WinDivertGetDriverFileName(LPWSTR sys_str)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register event log. It is not an error if this function fails.
|
||||
*/
|
||||
static void WinDivertRegisterEventSource(const wchar_t *windivert_sys)
|
||||
{
|
||||
HKEY key;
|
||||
size_t len;
|
||||
DWORD types = 7;
|
||||
|
||||
if (!WinDivertStrLen(windivert_sys, MAX_PATH, &len))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (RegCreateKeyExA(HKEY_LOCAL_MACHINE,
|
||||
"System\\CurrentControlSet\\Services\\EventLog\\System\\WinDivert",
|
||||
0, NULL, REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &key, NULL)
|
||||
!= ERROR_SUCCESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
RegSetValueExW(key, L"EventMessageFile", 0, REG_SZ, (LPBYTE)windivert_sys,
|
||||
(len + 1) * sizeof(wchar_t));
|
||||
RegSetValueExA(key, "TypesSupported", 0, REG_DWORD, (LPBYTE)&types,
|
||||
sizeof(types));
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
/*
|
||||
* Install the WinDivert driver.
|
||||
*/
|
||||
@@ -324,6 +351,9 @@ static BOOLEAN WinDivertDriverInstall(VOID)
|
||||
goto WinDivertDriverInstallExit;
|
||||
}
|
||||
|
||||
// Register event logging:
|
||||
WinDivertRegisterEventSource(windivert_sys);
|
||||
|
||||
WinDivertDriverInstallExit:
|
||||
|
||||
success = (service != NULL);
|
||||
@@ -356,7 +386,7 @@ WinDivertDriverInstallExit:
|
||||
ReleaseMutex(mutex);
|
||||
CloseHandle(mutex);
|
||||
SetLastError(err);
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* WINDIVERT HELPER IMPLEMENTATION */
|
||||
/****************************************************************************/
|
||||
@@ -2149,8 +2144,8 @@ static BOOL WinDivertCondExecFilter(PWINDIVERT_FILTER filter, UINT length,
|
||||
{
|
||||
INT16 ip;
|
||||
UINT16 succ, fail;
|
||||
BOOL result[WINDIVERT_FILTER_MAXLEN];
|
||||
BOOL result_succ, result_fail, result_test;
|
||||
BOOLEAN result[WINDIVERT_FILTER_MAXLEN];
|
||||
BOOLEAN result_succ, result_fail, result_test;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
/*
|
||||
* NOTE: This is the low-level interface to the WinDivert device driver.
|
||||
* This interface should not be used directly, instead use the high-level
|
||||
* interface provided by the divert API.
|
||||
* interface provided by the WinDivert API.
|
||||
*/
|
||||
|
||||
#define WINDIVERT_KERNEL
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ ENVS="i686-w64-mingw32 x86_64-w64-mingw32"
|
||||
|
||||
if [ "$1" = "debug" ]
|
||||
then
|
||||
MSVCRT=-lmsvcrt
|
||||
EXTRA_OPTS="-lmsvcrt -include stdio.h"
|
||||
fi
|
||||
|
||||
for ENV in $ENVS
|
||||
@@ -66,7 +66,7 @@ do
|
||||
CC="$ENV-gcc"
|
||||
COPTS="-fno-ident -shared -Wall -Wno-pointer-to-int-cast -Os -Iinclude/
|
||||
-Wl,--enable-stdcall-fixup -Wl,--entry=${MANGLE}WinDivertDllEntry"
|
||||
CLIBS="-lkernel32 -ladvapi32 $MSVCRT"
|
||||
CLIBS="-lkernel32 -ladvapi32 $EXTRA_OPTS"
|
||||
STRIP="$ENV-strip"
|
||||
DLLTOOL="$ENV-dlltool"
|
||||
if [ -x "`which $CC`" ]
|
||||
|
||||
+79
-4
@@ -32,7 +32,6 @@
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <ntifs.h>
|
||||
#include <ntddk.h>
|
||||
#include <fwpsk.h>
|
||||
@@ -44,6 +43,7 @@
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "windivert_device.h"
|
||||
#include "windivert_log.h"
|
||||
|
||||
/*
|
||||
* WDK function declaration cruft.
|
||||
@@ -304,6 +304,7 @@ static LONGLONG counts_per_ms = 0;
|
||||
static POOL_TYPE non_paged_pool = NonPagedPool;
|
||||
static MM_PAGE_PRIORITY no_write_flag = 0;
|
||||
static MM_PAGE_PRIORITY no_exec_flag = 0;
|
||||
static LONG64 num_opens = 0;
|
||||
|
||||
/*
|
||||
* Priorities.
|
||||
@@ -491,6 +492,8 @@ static void windivert_reflect_event_notify(context_t context,
|
||||
static void windivert_reflect_established_notify(context_t context,
|
||||
LONGLONG timestamp);
|
||||
extern void windivert_reflect_worker(IN WDFWORKITEM item);
|
||||
static void windivert_log_event(PEPROCESS process, PDRIVER_OBJECT driver,
|
||||
const wchar_t *msg_str);
|
||||
|
||||
/*
|
||||
* WinDivert sublayer GUIDs
|
||||
@@ -1245,11 +1248,11 @@ driver_entry_exit:
|
||||
/*
|
||||
* WinDivert driver unload routine.
|
||||
*/
|
||||
extern VOID windivert_unload(IN WDFDRIVER driver)
|
||||
extern VOID windivert_unload(IN WDFDRIVER driver_0)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(driver);
|
||||
|
||||
PDRIVER_OBJECT driver = WdfDriverWdmGetDriverObject(driver_0);
|
||||
windivert_driver_unload();
|
||||
windivert_log_event(PsGetCurrentProcess(), driver, L"UNLOAD");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3116,6 +3119,7 @@ windivert_ioctl_bad_flags:
|
||||
UINT32 process_id;
|
||||
WINDIVERT_LAYER layer;
|
||||
UINT8 filter_len;
|
||||
WDFDEVICE device;
|
||||
|
||||
ioctl = (PWINDIVERT_IOCTL)inbuf;
|
||||
filter_flags = ioctl->startup.flags;
|
||||
@@ -3172,8 +3176,15 @@ windivert_ioctl_bad_flags:
|
||||
context->reflect.open = FALSE;
|
||||
context->shutdown_recv_enabled =
|
||||
(layer != WINDIVERT_LAYER_REFLECT);
|
||||
device = context->device;
|
||||
KeReleaseInStackQueuedSpinLock(&lock_handle);
|
||||
|
||||
if (InterlockedIncrement64(&num_opens) == 1)
|
||||
{
|
||||
PDRIVER_OBJECT driver = WdfDriverWdmGetDriverObject(
|
||||
WdfDeviceGetDriver(device));
|
||||
windivert_log_event(process, driver, L"LOAD");
|
||||
}
|
||||
windivert_reflect_open_event(context);
|
||||
|
||||
status = windivert_install_callouts(context, layer, filter_flags);
|
||||
@@ -6182,3 +6193,67 @@ void windivert_reflect_worker(IN WDFWORKITEM item)
|
||||
KeReleaseInStackQueuedSpinLock(&lock_handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Log a driver event.
|
||||
*/
|
||||
static void windivert_log_event(PEPROCESS process, PDRIVER_OBJECT driver,
|
||||
const wchar_t *msg_str)
|
||||
{
|
||||
const wchar_t windivert_str[] = WINDIVERT_DEVICE_NAME
|
||||
WINDIVERT_VERSION_LSTR;
|
||||
wchar_t pid_str[16];
|
||||
size_t windivert_size = sizeof(windivert_str), msg_size, pid_size, size;
|
||||
UNICODE_STRING string;
|
||||
UINT8 *str;
|
||||
PIO_ERROR_LOG_PACKET packet;
|
||||
NTSTATUS status;
|
||||
|
||||
size = ERROR_LOG_MAXIMUM_SIZE - sizeof(wchar_t) -
|
||||
(sizeof(IO_ERROR_LOG_PACKET) + windivert_size + sizeof(pid_str));
|
||||
status = RtlStringCbLengthW(msg_str, size, &msg_size);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
msg_size += sizeof(wchar_t);
|
||||
|
||||
if (process != NULL)
|
||||
{
|
||||
string.Length = 0;
|
||||
string.MaximumLength = sizeof(pid_str);
|
||||
string.Buffer = pid_str;
|
||||
status = RtlIntegerToUnicodeString(
|
||||
(UINT32)(ULONG_PTR)PsGetProcessId(process), 10, &string);
|
||||
pid_size = string.Length + sizeof(wchar_t);
|
||||
}
|
||||
if (process == NULL || !NT_SUCCESS(status))
|
||||
{
|
||||
pid_str[0] = pid_str[1] = pid_str[2] = L'?';
|
||||
pid_str[3] = L'\0';
|
||||
pid_size = 4 * sizeof(wchar_t);
|
||||
}
|
||||
|
||||
size = sizeof(IO_ERROR_LOG_PACKET) + windivert_size + msg_size + pid_size;
|
||||
if (size > ERROR_LOG_MAXIMUM_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
packet = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(driver, (UCHAR)size);
|
||||
if (packet == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
RtlZeroMemory(packet, size);
|
||||
packet->NumberOfStrings = 3;
|
||||
packet->StringOffset = sizeof(IO_ERROR_LOG_PACKET);
|
||||
packet->ErrorCode = WINDIVERT_INFO_EVENT;
|
||||
str = (UINT8 *)packet + packet->StringOffset;
|
||||
RtlCopyMemory(str, windivert_str, windivert_size);
|
||||
str += windivert_size;
|
||||
RtlCopyMemory(str, msg_str, msg_size);
|
||||
str += msg_size;
|
||||
RtlCopyMemory(str, pid_str, pid_size);
|
||||
|
||||
IoWriteErrorLogEntry(packet);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <windows.h>
|
||||
#include <ntverp.h>
|
||||
|
||||
#include "windivert_log.rc"
|
||||
|
||||
#define VER_FILETYPE VFT_DRV
|
||||
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
|
||||
#define VER_FILEDESCRIPTION_STR \
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MessageCompile Include="windivert_log.mc">
|
||||
<RCFilePath>.</RCFilePath>
|
||||
<HeaderFilePath>.</HeaderFilePath>
|
||||
</MessageCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="windivert.rc" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
;/*
|
||||
; * windivert_log.mc
|
||||
; * (C) 2019, all rights reserved,
|
||||
; *
|
||||
; * This file is part of WinDivert.
|
||||
; *
|
||||
; * WinDivert is free software: you can redistribute it and/or modify it under
|
||||
; * the terms of the GNU Lesser General Public License as published by the
|
||||
; * Free Software Foundation, either version 3 of the License, or (at your
|
||||
; * option) any later version.
|
||||
; *
|
||||
; * This program is distributed in the hope that it will be useful, but
|
||||
; * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
; * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
; * License for more details.
|
||||
; *
|
||||
; * You should have received a copy of the GNU Lesser General Public License
|
||||
; * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
; *
|
||||
; * WinDivert is free software; you can redistribute it and/or modify it under
|
||||
; * the terms of the GNU General Public License as published by the Free
|
||||
; * Software Foundation; either version 2 of the License, or (at your option)
|
||||
; * any later version.
|
||||
; *
|
||||
; * This program is distributed in the hope that it will be useful, but
|
||||
; * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
; * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
; * for more details.
|
||||
; *
|
||||
; * You should have received a copy of the GNU General Public License along
|
||||
; * with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
; * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
; */
|
||||
|
||||
MessageIdTypedef=NTSTATUS
|
||||
|
||||
SeverityNames = (
|
||||
Success = 0x0:STATUS_SEVERITY_SUCCESS
|
||||
Informational = 0x1:STATUS_SEVERITY_INFORMATIONAL
|
||||
Warning = 0x2:STATUS_SEVERITY_WARNING
|
||||
Error = 0x3:STATUS_SEVERITY_ERROR
|
||||
)
|
||||
|
||||
FacilityNames = (
|
||||
System = 0x0:FACILITY_SYSTEM
|
||||
Runtime = 0x2:FACILITY_RUNTIME
|
||||
Stubs = 0x3:FACILITY_STUBS
|
||||
Io = 0x4:FACILITY_IO_ERROR_CODE
|
||||
WinDivert = 0x574:FACILITY_WINDIVERT
|
||||
)
|
||||
|
||||
MessageId=0x312D
|
||||
Facility=WinDivert
|
||||
Severity=Informational
|
||||
SymbolicName=WINDIVERT_INFO_EVENT
|
||||
Language=English
|
||||
%2 %3 (processId=%4)
|
||||
.
|
||||
|
||||
Reference in New Issue
Block a user