DriverLoader: Add fortdl_driver_path()

This commit is contained in:
Nodir Temirkhodjaev 2021-10-31 19:29:12 +03:00
parent 39190c7e71
commit 6f38cc6f08
6 changed files with 160 additions and 10 deletions

View File

@ -2,12 +2,102 @@
#include "fortdl.h"
static void fortdl_load(PCUNICODE_STRING driverPath)
{
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Load: %w\n", driverPath);
}
static void fortdl_init(PDRIVER_OBJECT driver, PVOID context, ULONG count)
{
PWSTR driverPath = context;
UNUSED(context);
UNUSED(count);
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Entry: %d\n", count);
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Init: %d\n", count);
/* Load the driver */
{
UNICODE_STRING path;
RtlInitUnicodeString(&path, driverPath);
fortdl_load(&path);
}
/* Free the allocated driver path */
ExFreePool(context);
}
static NTSTATUS fortdl_reg_value(HANDLE regKey, PUNICODE_STRING valueName, PWSTR *out_path)
{
NTSTATUS status;
ULONG keyInfoSize;
status = ZwQueryValueKey(regKey, valueName, KeyValueFullInformation, NULL, 0, &keyInfoSize);
if (status != STATUS_BUFFER_TOO_SMALL || status != STATUS_BUFFER_OVERFLOW)
return status;
PKEY_VALUE_FULL_INFORMATION keyInfo = fortdl_alloc(keyInfoSize);
if (keyInfo == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
status = ZwQueryValueKey(
regKey, valueName, KeyValueFullInformation, keyInfo, keyInfoSize, &keyInfoSize);
if (NT_SUCCESS(status)) {
const PUCHAR src = ((const PUCHAR) keyInfo + keyInfo->DataOffset);
const ULONG len = keyInfo->DataLength;
PWSTR buf = ExAllocatePool(NonPagedPool, len);
if (buf == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
} else {
RtlCopyMemory(buf, src, len);
*out_path = buf;
}
}
fortdl_free(keyInfo);
return status;
}
static NTSTATUS fortdl_driver_path(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path, PWSTR *out_path)
{
NTSTATUS status;
#if defined(FORT_WIN7_COMPAT)
UNUSED(driver);
HANDLE regKey;
OBJECT_ATTRIBUTES objectAttr;
InitializeObjectAttributes(
&objectAttr, reg_path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwOpenKey(&regKey, KEY_QUERY_VALUE, &objectAttr);
if (!NT_SUCCESS(status))
return status;
UNICODE_STRING valueName;
RtlInitUnicodeString(&valueName, L"ImagePath");
status = fortdl_reg_value(regKey, &valueName, out_path);
ZwClose(regKey);
#else
UNUSED(reg_path);
UNICODE_STRING path;
status = IoQueryFullDriverPath(driver, &path);
if (NT_SUCCESS(status)) {
*out_path = path.Buffer;
}
#endif
return status;
}
NTSTATUS
@ -18,10 +108,19 @@ DriverLoaderEntry
#endif
(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
UNUSED(reg_path);
NTSTATUS status;
PWSTR driverPath = NULL;
status = fortdl_driver_path(driver, reg_path, &driverPath);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Entry: Error: %x\n",
status);
return status;
}
/* Delay the initialization until other drivers have finished loading */
IoRegisterDriverReinitialization(driver, fortdl_init, NULL);
IoRegisterDriverReinitialization(driver, fortdl_init, driverPath);
return STATUS_SUCCESS;
}

View File

@ -3,4 +3,9 @@
#include "../fortdrv.h"
#define FORT_LOADER_POOL_TAG 'LwfF'
#define fortdl_alloc(size) fort_mem_alloc((size), FORT_LOADER_POOL_TAG)
#define fortdl_free(p) fort_mem_free((p), FORT_LOADER_POOL_TAG)
#endif // FORTDL_H

View File

@ -1,5 +1,12 @@
#include "um_ntddk.h"
NTSTATUS IoQueryFullDriverPath(PDRIVER_OBJECT DriverObject, PUNICODE_STRING FullPath)
{
UNUSED(DriverObject);
UNUSED(FullPath);
return 0;
}
VOID IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject,
PDRIVER_REINITIALIZE DriverReinitializationRoutine, PVOID Context)
{

View File

@ -7,6 +7,9 @@
extern "C" {
#endif
FORT_API NTSTATUS IoQueryFullDriverPath(
_In_ PDRIVER_OBJECT DriverObject, _Out_ PUNICODE_STRING FullPath);
//
// Define driver reinitialization routine type.
//
@ -15,8 +18,8 @@ typedef VOID DRIVER_REINITIALIZE(PDRIVER_OBJECT DriverObject, PVOID Context, ULO
typedef DRIVER_REINITIALIZE *PDRIVER_REINITIALIZE;
FORT_API VOID IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject,
PDRIVER_REINITIALIZE DriverReinitializationRoutine, PVOID Context);
FORT_API VOID IoRegisterDriverReinitialization(_In_ PDRIVER_OBJECT DriverObject,
_In_ PDRIVER_REINITIALIZE DriverReinitializationRoutine, _In_opt_ PVOID Context);
#ifdef __cplusplus
} // extern "C"

View File

@ -21,6 +21,11 @@ void ExFreePoolWithTag(PVOID p, ULONG tag)
HeapFree(GetProcessHeap(), 0, p);
}
void ExFreePool(PVOID p)
{
UNUSED(p);
}
PVOID ExAllocatePool2(POOL_FLAGS flags, SIZE_T size, ULONG tag)
{
UNUSED(flags);

View File

@ -5,9 +5,9 @@
#pragma warning(push)
#pragma warning(disable : 4005) // suppress warning: C4005: macro redefinition
#include <winternl.h>
#include <ntstatus.h>
#include <ifdef.h>
#include <ntstatus.h>
#include <winternl.h>
#include <ws2def.h>
#include <ws2ipdef.h>
#pragma warning(pop)
@ -166,6 +166,27 @@ typedef struct
short Weekday; // range [0..6] == [Sunday..Saturday]
} TIME_FIELDS, *PTIME_FIELDS;
typedef struct _KEY_VALUE_FULL_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
WCHAR Name[1]; // Variable size
// Data[1]; // Variable size data not declared
} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
typedef enum _KEY_VALUE_INFORMATION_CLASS {
KeyValueBasicInformation,
KeyValueFullInformation,
KeyValuePartialInformation,
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64,
KeyValueLayerInformation,
MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum
} KEY_VALUE_INFORMATION_CLASS;
#define DPFLTR_IHVNETWORK_ID 0
#define DPFLTR_ERROR_LEVEL 0
FORT_API ULONG DbgPrintEx(ULONG componentId, ULONG level, PCSTR format, ...);
@ -175,11 +196,13 @@ FORT_API ULONG DbgPrintEx(ULONG componentId, ULONG level, PCSTR format, ...);
#define NonPagedPool 0
FORT_API PVOID ExAllocatePoolWithTag(PVOID type, SIZE_T size, ULONG tag);
FORT_API void ExFreePoolWithTag(PVOID p, ULONG tag);
FORT_API PVOID ExAllocatePool(PVOID type, SIZE_T size);
FORT_API void ExFreePool(PVOID p);
typedef ULONG64 POOL_FLAGS;
#define POOL_FLAG_UNINITIALIZED 0x0000000000000002UI64 // Don't zero-initialize allocation
#define POOL_FLAG_NON_PAGED 0x0000000000000040UI64 // Non paged pool NX
#define POOL_FLAG_PAGED 0x0000000000000100UI64 // Paged pool
#define POOL_FLAG_UNINITIALIZED 0x0000000000000002UI64 // Don't zero-initialize allocation
#define POOL_FLAG_NON_PAGED 0x0000000000000040UI64 // Non paged pool NX
#define POOL_FLAG_PAGED 0x0000000000000100UI64 // Paged pool
FORT_API PVOID ExAllocatePool2(POOL_FLAGS flags, SIZE_T size, ULONG tag);
FORT_API PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP irp);
@ -245,6 +268,14 @@ FORT_API void KeQuerySystemTime(PLARGE_INTEGER time);
FORT_API void ExSystemTimeToLocalTime(PLARGE_INTEGER systemTime, PLARGE_INTEGER localTime);
FORT_API void RtlTimeToTimeFields(PLARGE_INTEGER time, PTIME_FIELDS timeFields);
FORT_API NTSTATUS ZwOpenKey(
PHANDLE keyHandle, ACCESS_MASK desiredAccess, POBJECT_ATTRIBUTES objectAttributes);
FORT_API NTSTATUS ZwClose(HANDLE handle);
FORT_API NTSTATUS ZwQueryValueKey(HANDLE keyHandle, PUNICODE_STRING valueName,
KEY_VALUE_INFORMATION_CLASS keyValueInformationClass, PVOID keyValueInformation,
ULONG length, PULONG resultLength);
#ifdef __cplusplus
} // extern "C"
#endif