DriverLoader: Add fortdl_load_file()

This commit is contained in:
Nodir Temirkhodjaev 2021-11-01 12:12:02 +03:00
parent 6f38cc6f08
commit a7f3c408c5
4 changed files with 155 additions and 10 deletions

View File

@ -2,32 +2,112 @@
#include "fortdl.h" #include "fortdl.h"
static void fortdl_load(PCUNICODE_STRING driverPath) #define FORTDL_MAX_FILE_SIZE (4 * 1024 * 1024)
static NTSTATUS fortdl_read_file(HANDLE fileHandle, PUCHAR *outData)
{ {
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Load: %w\n", driverPath); NTSTATUS status;
// Get File Size
DWORD fileSize = 0;
{
IO_STATUS_BLOCK statusBlock;
FILE_STANDARD_INFORMATION fileInfo;
status = ZwQueryInformationFile(
fileHandle, &statusBlock, &fileInfo, sizeof(fileInfo), FileStandardInformation);
if (!NT_SUCCESS(status))
return status;
if (fileInfo.EndOfFile.HighPart != 0 || fileInfo.EndOfFile.LowPart <= 0
|| fileInfo.EndOfFile.LowPart > FORTDL_MAX_FILE_SIZE)
return STATUS_FILE_NOT_SUPPORTED;
fileSize = fileInfo.EndOfFile.LowPart;
}
// Allocate Buffer
PUCHAR data = fortdl_alloc(fileSize);
if (data == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
// Read File
DWORD dataSize = 0;
do {
IO_STATUS_BLOCK statusBlock;
status = ZwReadFile(fileHandle, NULL, NULL, NULL, &statusBlock, data + dataSize,
fileSize - dataSize, NULL, NULL);
if (!NT_SUCCESS(status) || statusBlock.Information == 0) {
fortdl_free(data);
return NT_SUCCESS(status) ? STATUS_FILE_NOT_AVAILABLE : status;
}
dataSize += (DWORD) statusBlock.Information;
} while (dataSize < fileSize);
*outData = data;
return status;
}
static NTSTATUS fortdl_load_file(PCWSTR driverPath, PUCHAR *outData)
{
NTSTATUS status;
DbgPrintEx(
DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Load File: %w\n", driverPath);
// Open File
HANDLE fileHandle;
{
UNICODE_STRING path;
RtlInitUnicodeString(&path, driverPath);
OBJECT_ATTRIBUTES fileAttr;
InitializeObjectAttributes(
&fileAttr, &path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
IO_STATUS_BLOCK statusBlock;
status = ZwOpenFile(&fileHandle, GENERIC_READ | SYNCHRONIZE, &fileAttr, &statusBlock, 0,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(status))
return status;
}
status = fortdl_read_file(fileHandle, outData);
ZwClose(fileHandle);
return status;
} }
static void fortdl_init(PDRIVER_OBJECT driver, PVOID context, ULONG count) static void fortdl_init(PDRIVER_OBJECT driver, PVOID context, ULONG count)
{ {
PWSTR driverPath = context; NTSTATUS status;
UNUSED(context); UNUSED(context);
UNUSED(count); UNUSED(count);
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Init: %d\n", count); DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "FORT: Loader Init: %d\n", count);
/* Load the driver */ /* Load the driver file */
PUCHAR data = NULL;
{ {
UNICODE_STRING path; status = fortdl_load_file(context, &data);
RtlInitUnicodeString(&path, driverPath); /* Free the allocated driver path */
fortdl_load(&path); ExFreePool(context);
} }
/* Free the allocated driver path */ if (!NT_SUCCESS(status)) {
ExFreePool(context); DbgPrintEx(
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) static NTSTATUS fortdl_reg_value(HANDLE regKey, PUNICODE_STRING valueName, PWSTR *out_path)
{ {
NTSTATUS status; NTSTATUS status;
@ -63,6 +143,8 @@ static NTSTATUS fortdl_reg_value(HANDLE regKey, PUNICODE_STRING valueName, PWSTR
return status; return status;
} }
#endif
static NTSTATUS fortdl_driver_path(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path, PWSTR *out_path) static NTSTATUS fortdl_driver_path(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path, PWSTR *out_path)
{ {
NTSTATUS status; NTSTATUS status;

View File

@ -4,7 +4,7 @@ NTSTATUS IoQueryFullDriverPath(PDRIVER_OBJECT DriverObject, PUNICODE_STRING Full
{ {
UNUSED(DriverObject); UNUSED(DriverObject);
UNUSED(FullPath); UNUSED(FullPath);
return 0; return STATUS_SUCCESS;
} }
VOID IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject, VOID IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject,

View File

@ -259,3 +259,43 @@ void IoQueueWorkItemEx(
UNUSED(queueType); UNUSED(queueType);
UNUSED(context); UNUSED(context);
} }
NTSTATUS ZwOpenFile(PHANDLE fileHandle, ACCESS_MASK desiredAccess,
POBJECT_ATTRIBUTES objectAttributes, PIO_STATUS_BLOCK ioStatusBlock, ULONG shareAccess,
ULONG openOptions)
{
UNUSED(fileHandle);
UNUSED(desiredAccess);
UNUSED(objectAttributes);
UNUSED(ioStatusBlock);
UNUSED(shareAccess);
UNUSED(openOptions);
return STATUS_SUCCESS;
}
NTSTATUS ZwQueryInformationFile(HANDLE fileHandle, PIO_STATUS_BLOCK ioStatusBlock,
PVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass)
{
UNUSED(fileHandle);
UNUSED(ioStatusBlock);
UNUSED(fileInformation);
UNUSED(length);
UNUSED(fileInformationClass);
return STATUS_SUCCESS;
}
NTSTATUS ZwReadFile(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, PVOID apcContext,
PIO_STATUS_BLOCK ioStatusBlock, PVOID buffer, ULONG length, PLARGE_INTEGER byteOffset,
PULONG key)
{
UNUSED(fileHandle);
UNUSED(event);
UNUSED(apcRoutine);
UNUSED(apcContext);
UNUSED(ioStatusBlock);
UNUSED(buffer);
UNUSED(length);
UNUSED(byteOffset);
UNUSED(key);
return STATUS_SUCCESS;
}

View File

@ -187,6 +187,20 @@ typedef enum _KEY_VALUE_INFORMATION_CLASS {
MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum
} KEY_VALUE_INFORMATION_CLASS; } KEY_VALUE_INFORMATION_CLASS;
// Collision with winternl.h
// typedef enum _FILE_INFORMATION_CLASS {
#define FileBasicInformation 4
#define FileStandardInformation 5
typedef struct _FILE_STANDARD_INFORMATION
{
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG NumberOfLinks;
BOOLEAN DeletePending;
BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
#define DPFLTR_IHVNETWORK_ID 0 #define DPFLTR_IHVNETWORK_ID 0
#define DPFLTR_ERROR_LEVEL 0 #define DPFLTR_ERROR_LEVEL 0
FORT_API ULONG DbgPrintEx(ULONG componentId, ULONG level, PCSTR format, ...); FORT_API ULONG DbgPrintEx(ULONG componentId, ULONG level, PCSTR format, ...);
@ -276,6 +290,15 @@ FORT_API NTSTATUS ZwQueryValueKey(HANDLE keyHandle, PUNICODE_STRING valueName,
KEY_VALUE_INFORMATION_CLASS keyValueInformationClass, PVOID keyValueInformation, KEY_VALUE_INFORMATION_CLASS keyValueInformationClass, PVOID keyValueInformation,
ULONG length, PULONG resultLength); ULONG length, PULONG resultLength);
FORT_API NTSTATUS ZwOpenFile(PHANDLE fileHandle, ACCESS_MASK desiredAccess,
POBJECT_ATTRIBUTES objectAttributes, PIO_STATUS_BLOCK ioStatusBlock, ULONG shareAccess,
ULONG openOptions);
FORT_API NTSTATUS ZwQueryInformationFile(HANDLE fileHandle, PIO_STATUS_BLOCK ioStatusBlock,
PVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass);
FORT_API NTSTATUS ZwReadFile(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine,
PVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, PVOID buffer, ULONG length,
PLARGE_INTEGER byteOffset, PULONG key);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif