mirror of
https://github.com/tnodir/fort
synced 2024-11-15 07:25:18 +00:00
DriverLoader: Add fortdl_load_file()
This commit is contained in:
parent
6f38cc6f08
commit
a7f3c408c5
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user