DriverLoader: Move file loading to util.

This commit is contained in:
Nodir Temirkhodjaev 2021-11-01 20:29:13 +03:00
parent 4ce9bf1540
commit 0440f4f956
3 changed files with 84 additions and 88 deletions

View File

@ -4,7 +4,9 @@
#define FORT_UTIL_POOL_TAG 'UwfF'
FORT_API NTSTATUS fort_reg_value(HANDLE regKey, PUNICODE_STRING valueName, PWSTR *outData)
#define FORT_MAX_FILE_SIZE (4 * 1024 * 1024)
static NTSTATUS fort_reg_value(HANDLE regKey, PUNICODE_STRING valueName, PWSTR *outData)
{
NTSTATUS status;
@ -75,3 +77,65 @@ FORT_API NTSTATUS fort_driver_path(PDRIVER_OBJECT driver, PUNICODE_STRING regPat
return status;
}
FORT_API NTSTATUS fort_file_read(HANDLE fileHandle, ULONG poolTag, PUCHAR *outData, DWORD *outSize)
{
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 > FORT_MAX_FILE_SIZE)
return STATUS_FILE_NOT_SUPPORTED;
fileSize = fileInfo.EndOfFile.LowPart;
}
// Allocate Buffer
PUCHAR data = fort_mem_alloc(fileSize, poolTag);
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) {
fort_mem_free(data, poolTag);
return NT_SUCCESS(status) ? STATUS_FILE_NOT_AVAILABLE : status;
}
dataSize += (DWORD) statusBlock.Information;
} while (dataSize < fileSize);
*outData = data;
*outSize = dataSize;
return status;
}
FORT_API NTSTATUS fort_file_open(PCWSTR filePath, HANDLE *outHandle)
{
UNICODE_STRING path;
RtlInitUnicodeString(&path, filePath);
OBJECT_ATTRIBUTES fileAttr;
InitializeObjectAttributes(
&fileAttr, &path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
IO_STATUS_BLOCK statusBlock;
return ZwOpenFile(outHandle, GENERIC_READ | SYNCHRONIZE, &fileAttr, &statusBlock, 0,
FILE_SYNCHRONOUS_IO_NONALERT);
}

View File

@ -7,10 +7,11 @@
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);
FORT_API NTSTATUS fort_file_read(HANDLE fileHandle, ULONG poolTag, PUCHAR *outData, DWORD *outSize);
FORT_API NTSTATUS fort_file_open(PCWSTR filePath, HANDLE *outHandle);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -4,9 +4,7 @@
#include "../fortutl.h"
#define FORTDL_MAX_FILE_SIZE (4 * 1024 * 1024)
static NTSTATUS fortdl_load_image(PUCHAR data, DWORD dataSize)
static NTSTATUS fortdl_load_image(PUCHAR data, DWORD dataSize, PUCHAR *image)
{
NTSTATUS status;
@ -15,86 +13,6 @@ static NTSTATUS fortdl_load_image(PUCHAR data, DWORD dataSize)
return STATUS_SUCCESS;
}
static NTSTATUS fortdl_read_file(HANDLE fileHandle, PUCHAR *outData, DWORD *outSize)
{
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;
*outSize = dataSize;
return status;
}
static NTSTATUS fortdl_load_file(PCWSTR driverPath, PUCHAR *outData, DWORD *outSize)
{
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;
}
// Read File
status = fortdl_read_file(fileHandle, outData, outSize);
ZwClose(fileHandle);
return status;
}
static void fortdl_init(PDRIVER_OBJECT driver, PVOID context, ULONG count)
{
NTSTATUS status;
@ -108,7 +26,20 @@ static void fortdl_init(PDRIVER_OBJECT driver, PVOID context, ULONG count)
PUCHAR data = NULL;
DWORD dataSize = 0;
{
status = fortdl_load_file(context, &data, &dataSize);
HANDLE fileHandle;
status = fort_file_open(context, &fileHandle);
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: Loader File Load: %w status=%d\n", (PCWSTR) context, status);
if (NT_SUCCESS(status)) {
status = fort_file_read(fileHandle, FORT_LOADER_POOL_TAG, &data, &dataSize);
ZwClose(fileHandle);
}
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: Loader File Read: %w status=%d size=%d\n", (PCWSTR) context, status,
dataSize);
/* Free the allocated driver path */
ExFreePool(context);
@ -117,7 +48,7 @@ static void fortdl_init(PDRIVER_OBJECT driver, PVOID context, ULONG count)
// Prepare the driver image
PUCHAR image = NULL;
if (NT_SUCCESS(status)) {
status = fortdl_load_image(data, dataSize);
status = fortdl_load_image(data, dataSize, &image);
/* Free the allocated driver file data */
fortdl_free(data);