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"
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)
{
PWSTR driverPath = context;
NTSTATUS status;
UNUSED(context);
UNUSED(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);
fortdl_load(&path);
/* Free the allocated driver path */
ExFreePool(context);
}
/* Free the allocated driver path */
ExFreePool(context);
if (!NT_SUCCESS(status)) {
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)
{
NTSTATUS status;
@ -63,6 +143,8 @@ static NTSTATUS fortdl_reg_value(HANDLE regKey, PUNICODE_STRING valueName, PWSTR
return status;
}
#endif
static NTSTATUS fortdl_driver_path(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path, PWSTR *out_path)
{
NTSTATUS status;

View File

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

View File

@ -259,3 +259,43 @@ void IoQueueWorkItemEx(
UNUSED(queueType);
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
} 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_ERROR_LEVEL 0
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,
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
} // extern "C"
#endif