Driver: Add fortutl.* for utility functions.

This commit is contained in:
Nodir Temirkhodjaev 2021-11-01 20:03:23 +03:00
parent a7f3c408c5
commit 4ce9bf1540
5 changed files with 127 additions and 81 deletions

View File

@ -17,6 +17,7 @@ SOURCES += \
forttds.c \ forttds.c \
forttlsf.c \ forttlsf.c \
forttmr.c \ forttmr.c \
fortutl.c \
fortwrk.c \ fortwrk.c \
loader/fortdl.c \ loader/fortdl.c \
wdm/um_fwpmk.c \ wdm/um_fwpmk.c \
@ -37,6 +38,7 @@ HEADERS += \
forttds.h \ forttds.h \
forttlsf.h \ forttlsf.h \
forttmr.h \ forttmr.h \
fortutl.h \
fortwrk.h \ fortwrk.h \
wdm/um_fwpmk.h \ wdm/um_fwpmk.h \
wdm/um_fwpsk.h \ wdm/um_fwpsk.h \

77
src/driver/fortutl.c Normal file
View File

@ -0,0 +1,77 @@
/* Fort Firewall Utilities */
#include "fortutl.h"
#define FORT_UTIL_POOL_TAG 'UwfF'
FORT_API NTSTATUS fort_reg_value(HANDLE regKey, PUNICODE_STRING valueName, PWSTR *outData)
{
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 = fort_mem_alloc(keyInfoSize, FORT_UTIL_POOL_TAG);
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);
*outData = buf;
}
}
fort_mem_free(keyInfo, FORT_UTIL_POOL_TAG);
return status;
}
FORT_API NTSTATUS fort_driver_path(PDRIVER_OBJECT driver, PUNICODE_STRING regPath, PWSTR *outPath)
{
NTSTATUS status;
#if defined(FORT_WIN7_COMPAT)
UNUSED(driver);
HANDLE regKey;
OBJECT_ATTRIBUTES objectAttr;
InitializeObjectAttributes(
&objectAttr, regPath, 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, outPath);
ZwClose(regKey);
#else
UNUSED(regPath);
UNICODE_STRING path;
status = IoQueryFullDriverPath(driver, &path);
if (NT_SUCCESS(status)) {
*outPath = path.Buffer;
}
#endif
return status;
}

18
src/driver/fortutl.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef FORTUTL_H
#define FORTUTL_H
#include "fortdrv.h"
#if defined(__cplusplus)
extern "C" {
#endif
FORT_API NTSTATUS fort_reg_value(HANDLE regKey, PUNICODE_STRING valueName, PWSTR *outData);
FORT_API NTSTATUS fort_driver_path(PDRIVER_OBJECT driver, PUNICODE_STRING regPath, PWSTR *outPath);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // FORTUTL_H

View File

@ -2,9 +2,20 @@
#include "fortdl.h" #include "fortdl.h"
#include "../fortutl.h"
#define FORTDL_MAX_FILE_SIZE (4 * 1024 * 1024) #define FORTDL_MAX_FILE_SIZE (4 * 1024 * 1024)
static NTSTATUS fortdl_read_file(HANDLE fileHandle, PUCHAR *outData) static NTSTATUS fortdl_load_image(PUCHAR data, DWORD dataSize)
{
NTSTATUS status;
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Load Image: %d\n", dataSize);
return STATUS_SUCCESS;
}
static NTSTATUS fortdl_read_file(HANDLE fileHandle, PUCHAR *outData, DWORD *outSize)
{ {
NTSTATUS status; NTSTATUS status;
@ -47,11 +58,12 @@ static NTSTATUS fortdl_read_file(HANDLE fileHandle, PUCHAR *outData)
} while (dataSize < fileSize); } while (dataSize < fileSize);
*outData = data; *outData = data;
*outSize = dataSize;
return status; return status;
} }
static NTSTATUS fortdl_load_file(PCWSTR driverPath, PUCHAR *outData) static NTSTATUS fortdl_load_file(PCWSTR driverPath, PUCHAR *outData, DWORD *outSize)
{ {
NTSTATUS status; NTSTATUS status;
@ -75,7 +87,8 @@ static NTSTATUS fortdl_load_file(PCWSTR driverPath, PUCHAR *outData)
return status; return status;
} }
status = fortdl_read_file(fileHandle, outData); // Read File
status = fortdl_read_file(fileHandle, outData, outSize);
ZwClose(fileHandle); ZwClose(fileHandle);
@ -93,95 +106,29 @@ static void fortdl_init(PDRIVER_OBJECT driver, PVOID context, ULONG count)
/* Load the driver file */ /* Load the driver file */
PUCHAR data = NULL; PUCHAR data = NULL;
DWORD dataSize = 0;
{ {
status = fortdl_load_file(context, &data); status = fortdl_load_file(context, &data, &dataSize);
/* Free the allocated driver path */ /* Free the allocated driver path */
ExFreePool(context); ExFreePool(context);
} }
// Prepare the driver image
PUCHAR image = NULL;
if (NT_SUCCESS(status)) {
status = fortdl_load_image(data, dataSize);
/* Free the allocated driver file data */
fortdl_free(data);
}
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DbgPrintEx( DbgPrintEx(
DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Init: Error: %x\n", status); DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Init: Error: %x\n", status);
} }
} }
#if defined(FORT_WIN7_COMPAT)
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;
}
#endif
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 NTSTATUS
#if defined(FORT_DRIVER) #if defined(FORT_DRIVER)
DriverEntry DriverEntry
@ -193,7 +140,7 @@ DriverLoaderEntry
NTSTATUS status; NTSTATUS status;
PWSTR driverPath = NULL; PWSTR driverPath = NULL;
status = fortdl_driver_path(driver, reg_path, &driverPath); status = fort_driver_path(driver, reg_path, &driverPath);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Entry: Error: %x\n", DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Entry: Error: %x\n",

View File

@ -3,4 +3,6 @@
#define FORT_AMALG #define FORT_AMALG
#define FORT_DRIVER #define FORT_DRIVER
#include "../fortutl.c"
#include "fortdl.c" #include "fortdl.c"