From d5e0277eb9489f3115779567fee3645bc99c86b5 Mon Sep 17 00:00:00 2001 From: Zac Lockard Date: Fri, 29 Sep 2023 18:25:03 -0700 Subject: Switch to final registry key loading paradigm --- .../MetadataManager/MetadataManagerInit.c | 201 +++++++++++++++++---- 1 file changed, 162 insertions(+), 39 deletions(-) (limited to 'filesys/miniFilter/MetadataManager/MetadataManagerInit.c') diff --git a/filesys/miniFilter/MetadataManager/MetadataManagerInit.c b/filesys/miniFilter/MetadataManager/MetadataManagerInit.c index 3b371360..dbedd3a8 100644 --- a/filesys/miniFilter/MetadataManager/MetadataManagerInit.c +++ b/filesys/miniFilter/MetadataManager/MetadataManagerInit.c @@ -86,6 +86,28 @@ FmmInstanceTeardownComplete ( #if DBG +typedef +NTSTATUS +(*PFN_IoOpenDriverRegistryKey) ( + PDRIVER_OBJECT DriverObject, + DRIVER_REGKEY_TYPE RegKeyType, + ACCESS_MASK DesiredAccess, + ULONG Flags, + PHANDLE DriverRegKey + ); + +PFN_IoOpenDriverRegistryKey +FmmGetIoOpenDriverRegistryKey ( + VOID + ); + +NTSTATUS +FmmOpenServiceParametersKey ( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING ServiceRegistryPath, + _Out_ PHANDLE ServiceParametersKey + ); + VOID FmmInitializeDebugLevel ( _In_ PDRIVER_OBJECT DriverObject, @@ -102,6 +124,8 @@ FmmInitializeDebugLevel ( #pragma alloc_text(INIT, DriverEntry) #if DBG +#pragma alloc_text(INIT, FmmGetIoOpenDriverRegistryKey) +#pragma alloc_text(INIT, FmmOpenServiceParametersKey) #pragma alloc_text(INIT, FmmInitializeDebugLevel) #endif @@ -300,18 +324,36 @@ Return Value: #if DBG -VOID -FmmInitializeDebugLevel ( +PFN_IoOpenDriverRegistryKey +FmmGetIoOpenDriverRegistryKey ( + VOID + ) +{ + static PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey = NULL; + UNICODE_STRING FunctionName = {0}; + + if (pIoOpenDriverRegistryKey == NULL) { + + RtlInitUnicodeString(&FunctionName, L"IoOpenDriverRegistryKey"); + + pIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&FunctionName); + } + + return pIoOpenDriverRegistryKey; +} + +NTSTATUS +FmmOpenServiceParametersKey ( _In_ PDRIVER_OBJECT DriverObject, - _In_ PUNICODE_STRING RegistryPath + _In_ PUNICODE_STRING ServiceRegistryPath, + _Out_ PHANDLE ServiceParametersKey ) /*++ Routine Description: - This routine tries to read the filter DebugLevel parameter from - the registry. This value will be found in the registry location - indicated by the RegistryPath passed in. + This routine opens the service parameters key, using the isolation-compliant + APIs when possible. Arguments: @@ -320,66 +362,82 @@ Arguments: RegistryPath - The path key passed to the driver during DriverEntry. + ServiceParametersKey - Returns a handle to the service parameters subkey. + Return Value: - None. + STATUS_SUCCESS if the function completes successfully. Otherwise a valid + NTSTATUS code is returned. --*/ { - OBJECT_ATTRIBUTES attributes; - OSVERSIONINFOW versionInfo; - HANDLE driverRegKey = NULL; NTSTATUS status; - ULONG resultLength; - UNICODE_STRING valueName; - UCHAR buffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( LONG )]; - - Globals.DebugLevel = DEBUG_TRACE_ERROR; - - RtlZeroMemory( &versionInfo, sizeof( versionInfo ) ); + PFN_IoOpenDriverRegistryKey pIoOpenDriverRegistryKey; + UNICODE_STRING Subkey; + HANDLE ParametersKey = NULL; + HANDLE ServiceRegKey = NULL; + OBJECT_ATTRIBUTES Attributes; // - // Determine the OS version being run. + // Open the parameters key to read values from the INF, using the API to + // open the key if possible // - versionInfo.dwOSVersionInfoSize = sizeof( versionInfo ); + pIoOpenDriverRegistryKey = FmmGetIoOpenDriverRegistryKey(); - status = RtlGetVersion( &versionInfo ); + if (pIoOpenDriverRegistryKey != NULL) { - if (!NT_SUCCESS( status )) { + // + // Open the parameters key using the API + // - goto cleanup; - } + status = pIoOpenDriverRegistryKey( DriverObject, + DriverRegKeyParameters, + KEY_READ, + 0, + &ParametersKey ); - // - // Open the desired registry key - // + if (!NT_SUCCESS( status )) { + + goto cleanup; + } + + } else { - if (versionInfo.dwBuildNumber >= 25952) { // - // Open the Parameters key for the service. + // Open specified service root key // - status = IoOpenDriverRegistryKey( DriverObject, - DriverRegKeyParameters, - KEY_READ, - 0, - &driverRegKey ); + InitializeObjectAttributes( &Attributes, + ServiceRegistryPath, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL ); + + status = ZwOpenKey( &ServiceRegKey, + KEY_READ, + &Attributes ); if (!NT_SUCCESS( status )) { goto cleanup; } - } else { - InitializeObjectAttributes( &attributes, - RegistryPath, + + // + // Open the parameters key relative to service key path + // + + RtlInitUnicodeString( &Subkey, L"Parameters" ); + + InitializeObjectAttributes( &Attributes, + &Subkey, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - NULL, + ServiceRegKey, NULL ); - status = ZwOpenKey( &driverRegKey, + status = ZwOpenKey( &ParametersKey, KEY_READ, - &attributes ); + &Attributes ); if (!NT_SUCCESS( status )) { @@ -387,6 +445,71 @@ Return Value: } } + // + // Return value to caller + // + + *ServiceParametersKey = ParametersKey; + +cleanup: + + if (ServiceRegKey != NULL) { + + ZwClose( ServiceRegKey ); + } + + return status; + +} + +VOID +FmmInitializeDebugLevel ( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath + ) +/*++ + +Routine Description: + + This routine tries to read the filter DebugLevel parameter from + the registry. This value will be found in the registry location + indicated by the RegistryPath passed in. + +Arguments: + + DriverObject - Pointer to driver object created by the system to + represent this driver. + + RegistryPath - The path key passed to the driver during DriverEntry. + +Return Value: + + None. + +--*/ +{ + HANDLE driverRegKey = NULL; + NTSTATUS status; + ULONG resultLength; + UNICODE_STRING valueName; + UCHAR buffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( LONG )]; + + Globals.DebugLevel = DEBUG_TRACE_ERROR; + + // + // Open service parameters key to query values from. + // + + status = FmmOpenServiceParametersKey( DriverObject, + RegistryPath, + &driverRegKey ); + + if (!NT_SUCCESS( status )) { + + driverRegKey = NULL; + goto cleanup; + } + // // Read the DebugFlags value from the registry. // -- cgit v1.3.1